How to use Http Client instead of cURL in CakePHP 3

I posted earlier “How to use HttpSocket instead of cURL in CakePHP 2“. In that blogpost I showed how easy it is to refactor your API requests from cURL to HttpSocket. In CakePHP3, HttpSocket is now Cake\Network\Http\Client and has been completely re-written from the ground up. CakePHP3 made cURL completely unnecessary with the new Http Client. Here are some examples to get you up to speed:

Basic requests

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?php
/* ----------------------------------------------------------------
* -- cURL example
*/
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => 'http://cakephp.org'
]);
$response = curl_exec($ch);
curl_close($ch);
/* ----------------------------------------------------------------
* -- CakePHP3 Http Client example
*/
use Cake\Network\Http\Client;
$http = new Client();
$response = $http->get('http://cakephp.org');
// Also try the full REST family:
$http->post('http://cakephp.org', ['key' => 'value']); // POST request
$http->put('http://cakephp.org', ['key' => 'value']); // PUT request
$http->patch('http://cakephp.org', ['key' => 'value']); // PATCH request
$http->delete('http://cakephp.org'); // DELETE request
?>

HttpSocket Request with basic HTTP authentication

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
/* ----------------------------------------------------------------
* -- cURL example
*/
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => 'http://cakephp.org',
CURLOPT_USERPWD => 'myusername:mypassword'
]);
$output = curl_exec($ch);
curl_close($ch);
/* ----------------------------------------------------------------
* -- CakePHP3 Http Client example
*/
use Cake\Network\Http\Client;
$http = new Client();
$response = $http->get('http://cakephp.org', [], [
'auth' => ['username' => 'myusername', 'password' => 'mypassword']
]);
?>

Send and receive JSON

Let’s assume we send a JSON payload in the body request, and we receive JSON in the response

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?php
$jsonPayload = json_encode(['key' => 'value']);
/* ----------------------------------------------------------------
* -- cURL example
*/
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $jsonPayload,
CURLOPT_URL => 'http://cakephp.org',
CURLOPT_HTTPHEADER => ['Content-Type:application/json', 'Content-Length: ' . strlen($jsonPayload)]
]);
$response = curl_exec($ch);
curl_close($ch);
$jsonDecoded = json_decode($response, true); // Returns an array
debug($jsonDecoded);
/* ----------------------------------------------------------------
* -- CakePHP3 Http Client example
*/
use Cake\Network\Http\Client;
$http = new Client();
$response = $http->post('http://cakephp.org', $jsonPayload, ['type' => 'json']);
debug($response->json);
?>

For more examples please look at the Http Client CakePHP book.

So again, what is your excuse to use cURL in your CakePHP3 project?

How to use HttpSocket instead of cURL in CakePHP 2

While browsing my Google Analytics, I got surprised how many people are still searching for CakePHP cURL solutions while CakePHP has it own build-in class (HttpSocket) with the very same functionality.

The main argument I hear for using cURL for your API requests, is because it has so many nice features. I like cURL and it helps me a lot, but I rather use what’s inside the CakePHP framework. HttpSocket has probably all the features you actually need and use. In this article I will show you how to refactor your app from cURL to CakePHP’s HttpSocket.

I will show some cURL vs HttpSocket examples for the following cases:

  • Basic GET request
  • Basic POST request
  • HttpSocket Request with basic HTTP authentication
  • HttpSocket Request with Cookies
  • HttpSocket Request that allows self-signed SSL connections
  • HttpSocket Request through a proxy

Basic GET request

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
/* ----------------------------------------------------------------
* -- cURL example
*/
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => 'http://cakephp.org'
]);
$response = curl_exec($ch);
curl_close($ch);
/* ----------------------------------------------------------------
* -- CakePHP HttpSocket example
*/
App::uses('HttpSocket', 'Network/Http');
$HttpSocket = new HttpSocket();
$response = $HttpSocket->get('http://cakephp.org');
?>

Basic POST request

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
/* ----------------------------------------------------------------
* -- cURL example
*/
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => 'http://cakephp.org',
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => [
'key1' => 'value1',
'key2' => 'value2'
]
]);
$response = curl_exec($ch);
curl_close($ch);
/* ----------------------------------------------------------------
* -- CakePHP HttpSocket example
*/
App::uses('HttpSocket', 'Network/Http');
$HttpSocket = new HttpSocket();
$response = $HttpSocket->post('http://cakephp.org', ['key' => 'value']);
?>

HttpSocket Request with basic HTTP authentication

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
/* ----------------------------------------------------------------
* -- cURL example
*/
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => 'http://cakephp.org',
CURLOPT_USERPWD => 'username:password'
]);
$output = curl_exec($ch);
curl_close($ch);
/* ----------------------------------------------------------------
* -- CakePHP HttpSocket example
* You can also use "Digest" instead of "Basic" as the first parameter
*/
App::uses('HttpSocket', 'Network/Http');
$HttpSocket = new HttpSocket();
$HttpSocket->configAuth('Basic', 'username', 'password');
$response = $HttpSocket->get('http://cakephp.org');
?>

HttpSocket Request with Cookies

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?php
/* ----------------------------------------------------------------
* -- cURL example
*/
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => 'http://cakephp.org',
CURLOPT_COOKIESESSION => true,
CURLOPT_COOKIEJAR => '/path/to/cookie.txt',
CURLOPT_COOKIEFILE => '/path/to/cookie.txt'
]);
$output = curl_exec($ch);
curl_close($ch);
/* ----------------------------------------------------------------
* -- CakePHP HttpSocket example
*/
App::uses('HttpSocket', 'Network/Http');
$HttpSocket = new HttpSocket();
$response = $HttpSocket->request([
'uri' => 'http://cakephp.org',
'cookies' => [
'CAKEPHP' => 'b6d3bca4d372dd6a58c4e46d2f60f0ef',
'cookieKey' => 'cookieValue'
]
]);
?>

HttpSocket Request that allows self-signed SSL connections

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
/* ----------------------------------------------------------------
* -- cURL example
*/
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => 'http://cakephp.org',
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_SSL_VERIFYPEER => false
]);
$output = curl_exec($ch);
curl_close($ch);
/* ----------------------------------------------------------------
* -- CakePHP HttpSocket example
* We have to supply an array when we initiate the HttpSocket:
*/
App::uses('HttpSocket', 'Network/Http');
$HttpSocket = new HttpSocket(['ssl_allow_self_signed' => true]);
$response = $HttpSocket->get('http://cakephp.org');
?>

HttpSocket Request through a proxy

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
/* ----------------------------------------------------------------
* -- cURL example
*/
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => 'http://cakephp.org',
CURLOPT_PROXY => 'proxy-host-or-ip.com:3128',
CURLOPT_PROXYUSERPWD => 'proxyusername:proxypassword'
]);
$output = curl_exec($ch);
curl_close($ch);
/* ----------------------------------------------------------------
* -- CakePHP HttpSocket example
* configProxy attributes: configProxy($host, $port = 3128, $method = null, $user = null, $pass = null)
*/
App::uses('HttpSocket', 'Network/Http');
$HttpSocket = new HttpSocket();
$HttpSocket->configProxy('proxy-host-or-ip.com', 3128, 'Basic', 'proxyusername', 'proxypassword') {
$response = $HttpSocket->get('http://cakephp.org');
?>

Some other quick fixes

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
/* User Agent */
$response = $HttpSocket->request([
'uri' => 'http://cakephp.org',
'header' => [
'User-Agent' => 'Internet Explorer 6 HAHA'
]
]);
/* PUT request */
$response = $HttpSocket->put('http://cakephp.org', ['key' => 'value']);
/* Alternative PUT/DELETE/PATCH/HEAD request */
$response = $HttpSocket->request([
'method' => 'HEAD',
'uri' => 'http://cakephp.org'
]);
/* Follow redirects */
$response = $HttpSocket->request([
'uri' => 'http://cakephp.org',
'redirect' => true // or an integer for max amount of redirects
]);
?>

So, what is your excuse to use cURL in your CakePHP project?

CakePHP Performance: Rewrite plugin assets in Nginx

This post dated from 2011. Today CakePHP has a better (and faster) dispatch handler for assets. However, for the best performance, this article is still very useful.

Lately I’m playing with the Nginx webserver. Nginx is a free, open-source, high-performance HTTP server hosting 7.5% of all webservers on the internet (that’s 20.5M webservers).

CakePHP plugin assets are served through PHP, which makes it obviously slower than serving it without invoking PHP. I found a little solution that speeds up every plugin asset by ~ 60ms. So when you have lots of images, css and javascript files in your plugins, you can speed up your page load time by several seconds!

One of the great benefits is the freedom and flexibility of the configuration files, so I played a bit with the ‘try_files functionality‘ which results in amazing performance improvements.

Read More

Five useful CakePHP functions I just discovered

This blogpost is focused on CakePHP 1.2 / 1.3

I don’t have to explain why CakePHP is such a brilliant PHP framework.. The good part with frameworks is that they include a rich reusable API library full of functions that will make life easier for most programmers. CakePHP is such a framework with an enormous rich library. I only know half of the functions but every day I discover some new great functions which some of them I want to share.

Read More

CakePHP No markup with formhelper input

Just a short blog post about CakePHP, I see loads of people around me who don’t want any markup like DIVS or LABELS around their form input elements. There are plenty reasons you don’t want those markup, for example when you need your form in a table.

I see colleagues using $form->select(); or $form->radio(); to avoid all the markup, but there’s a simple trick to hide all the additional elements and still benefit from all the magic features of $form->input();

Just add two parameters in the input options:

1
2
3
4
5
6
<?php
echo $this->Form->input('title', array(
'div' => false,
'label' => false
));
?>

How we built Twittermail in 48 hours

Disclaimer: This article was written in 2009 when Twittermail was one of the first major Twitter 3rd party apps. It’s a little outdated now, back in 2009 it was uncommon people had smartphones or a permanent internet connection. Also, this use case was focused on CakePHP 1.2, it’s very outdated now but still fun to read.

Okay, for those who don’t know Twittermail, Twittermail is an open idea by Boris Veldhuijzen van Zanten, he thought that it would be great if people could e-mail their tweets to Twitter.com.

This is potentially very useful for people who use mobile phones. Of course you can go to the mobile webpage of Twitter, but sending an e-mail is pretty much easier. Some older phones do not even contain a browser and only have e-mail functionality. Also a lot of businesses block Twitter.com on their corporate network but with Twittermail you can continually update your Twitter account even from your business e-mail address.

Those who register at Twittermail, get a secret unique email address like 1234abcde [AT] twittermail com. When you send an e-mail to this secret email address, it will get posted instantly to Twitter.com through the Twitter API.

Read More