Book review: CouchDB and PHP Web Development

Finally the new Book “CouchDB and PHP Web Development” written by Tim Juravich is ready an in my hands. It was my first experience as technical reviewer. The author contacted me by email and the editor sent me book chapters to review. Basically I gave my opinion, I test the code and I hunt for bugs. It was a great experience. Now is really cool to see the book in my hands.

As a general rule I don’t like the Beginner’s books. They normally fill various chapters with trivial things. Things that you can easily find within the project homepage, or you also can get thousands of articles in the Internet. Maybe the first 3 chapters are trivial things about NoSQL databases, how to set up a PHP environments, and we also can read about how to set up a github account. OK this book is not one exception, but it has something “different”. The author builds one application (a twitter clone) using PHP as backend languaje, CouchDB for the storage and Twitter’s Bootstrap for the frontend. It covers all the process from the beginning (setting up the environment) to the end (deploy the application to the cloud). The book is very interactive. It’s crowed by “Time for action” sections where the reader can build the application at the same time than he is reading. And to top it all the author also encourages the user to commit each change to one git repository.

My Conclusions
In my humble opinion is a good book, even with its trivial chapters (probably they are mandatory in this kind of books). If you read the book and you follow the all the “Time for action” sections you will have great picture about one real web application development process is and it also covers very well all CouchDB related things. Another good point for the author is the usage of newest front end technologies such as Twitter’s Bootstrap. Maybe I miss a bit the usage of TDD in the development process of the application but either way if fulfills its mission quite well.

Contact with me.
As I said before it was my first experience as a technical reviewer. It was a great experience for me. I really enjoyed a lot reading and commenting chapters. If you are writing a book and you need one reviewer, feel free to contact with me.

Building a simple Dependency Injection Container with PHP

If you are looking for a small Dependency Injection Container with PHP maybe you need have look to Pimple.

Pimple is a small Dependency Injection Container for PHP 5.3 that consists of just one file and one class (about 50 lines of code).

Now, keeping with my aim of reinvent the wheel, we will create a simple Dependency Injection Container basically to understand how does it work. Let’s start.

First of all: Do we really need a Dependency Injection Container (DIC)? If you are asking yourself this question, maybe you need to have look to Fabien Poetencier’s article.

We are going to work with a teorical problem like this:

Imagine we are going to build a service that uses one external REST API. We define your application with three classes:

  • App. The main application.
  • Proxy The part of the application that speaks with the external API
  • Curl. One curl wrapper to perform our http connections to the REST API

Our first approach can be:

[sourcecode language=”php”]
<?php
class App
{
private $proxy;

public function __construct()
{
echo "App::__construct\n";
$this->proxy = new Proxy();
}

public function hello()
{
return $this->proxy->hello();
}
}

class Proxy
{
private $curl;

public function __construct()
{
$this->curl = new Curl();
}

public function hello()
{
echo "Proxy::__construct\n";
return $this->curl->doGet();
}
}

class Curl
{
public function doGet()
{
echo "Curl::doGet\n";
return "Hello";
}
}

$app = new App();
echo $app->hello();

[/sourcecode]

If we execute the script:

[sourcecode language=”bash”]
php example1.php

App::__construct
Proxy::__construct
Curl::doGet
Hello
[/sourcecode]

It works but we have one problem. Our application is strongly coupled. As we can see App creates a new instance of Proxy within the constructor and Proxy creates a new instance of Curl. That’s a problem especially if we want to use TDD. What happens if we want to mock Curl requests to test the application without using the real external service?. Dependency injection can help us here. We can change our application to:

[sourcecode language=”php”]
<?php
class App
{
private $proxy;

public function __construct(Proxy $proxy)
{
echo "App::__construct\n";
$this->proxy = $proxy;
}

public function hello()
{
return $this->proxy->hello();
}
}

class Proxy
{
private $curl;

public function __construct(Curl $curl)
{
$this->curl = $curl;
}

public function hello()
{
echo "Proxy::__construct\n";
return $this->curl->doGet();
}
}

class Curl
{
public function doGet()
{
echo "Curl::doGet\n";
return "Hello";
}
}

$app = new App(new Proxy(new Curl()));
echo $app->hello();

[/sourcecode]

The outcome is exactly the same but now we can easily use mocks and use different configurations depending on the environment. Maybe your testing development does not have access to the real REST server.

Now our application isn’t coupled but as we can see our Dependency Injection becomes a mess. That’s one problem with DI. It’s pretty straightforward to inject simple things but when we have dependencies over a set of classes that’s becomes a difficult task. Because of that we can use Dependency Injection Containers.

If we choose Pimple as Dependency Injection Container we can refactor our application to:

[sourcecode language=”php”]
<?php
class App
{
private $proxy;

public function __construct(Pimple $container)
{
echo "App::__construct\n";
$this->proxy = $container[‘Proxy’];
}

public function hello()
{
return $this->proxy->hello();
}
}

class Proxy
{
private $curl;

public function __construct(Pimple $container)
{
$this->curl = $container[‘Curl’];
}

public function hello()
{
echo "Proxy::__construct\n";
return $this->curl->doGet();
}
}

class Curl
{
public function doGet()
{
echo "Curl::doGet\n";
return "Hello";
}
}

require_once ‘Pimple.php’;

$container = new Pimple();
$container[‘Curl’] = function ($c) {return new Curl();};
$container[‘Proxy’] = function ($c) {return new Proxy($c);};

$app = new App($container);
echo $app->hello();

[/sourcecode]

But what is my problem with Pimple? Basically my problem is that my IDE cannot autocomplete correctly $container is an instance of Pimple not the “real” instance. OK It instantiated on demand the classes but it’s done at runtime and the IDE don’t know about that. We can solve it using an extra PHPDoc to give hints to the IDE but we also can use a different approach. Instead of using Pimple we can use this script:

[sourcecode language=”php”]
<?php
class App
{
private $proxy;

public function __construct(Container $container)
{
echo "App::__construct\n";
$this->proxy = $container->getProxy();
}

public function hello()
{
echo "App::hello\n";
return $this->proxy->hello();
}
}

class Proxy
{
private $curl;

public function __construct(Container $container)
{
echo "Proxy::__construct\n";
$this->curl = $container->getCurl();
}

public function hello()
{
return $this->curl->doGet();
}
}

class Curl
{
public function doGet()
{
echo "Curl::doGet\n";
return "Hello";
}
}

class Container
{
public function getProxy()
{
return new Proxy($this);
}

public function getCurl()
{
return new Curl();
}
}

$app = new App(new Container());
echo $app->hello();
[/sourcecode]

The idea is the same than Pimple but now we have created our custom Dependency Injection Container without extending any library and now our IDE will autocomplete the fucntion names without problems. If we want to share objects instead creating new ones each time we call the factory function of the container we can change a little bit our Container (the same way than Pimple::share) with a simple singleton pattern:

[sourcecode language=”php”]
class Container
{
static $proxy;
public function shareProxy()
{
if (NULL === self::$proxy) self::$proxy = new Proxy($this);
return self::$proxy;
}

public function getCurl()
{
return new Curl();
}
}
[/sourcecode]

And that’s all. What do you think?

Building a simple SQL wrapper with PHP. Part 2.

In one of our last post we built a simple SQL wrapper with PHP. Now we are going to improve it a little bit. We area going to use a class Table instead of the table name. Why? Simple. We want to create triggers. OK we can create triggers directly in the database but sometimes our triggers need to perform operations outside the database, such as call a REST webservice, filesystem’s logs or things like that.

[sourcecode language=”php”]
<?php
class Storage
{
static $count = 0;

static function init()
{
self::$count = 0;
}

static function increment()
{
self::$count++;
}

static function decrement()
{
self::$count–;
}

static function get()
{
return self::$count;
}
}

class SqlTest extends PHPUnit_Framework_TestCase
{
public function setUp()
{
$this->dbh = new Conn(‘pgsql:dbname=db;host=localhost’, ‘gonzalo’, ‘password’);
$this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->dbh->forceRollback();
}

public function testInsertWithPostInsertShowingInsertedValues()
{
Storage::init();
$that = $this;
$this->dbh->transactional(function($dbh) use ($that) {
$sql = new Sql($that->dbh);
$users = new Table(‘users’);
$users->postInsert(function($values) {Storage::increment();});

$that->assertEquals(0, Storage::get());
$actual = $sql->insert($users, array(‘uid’ => 7, ‘name’ => ‘Gonzalo’, ‘surname’ => ‘Ayuso’));
$that->assertTrue($actual);

$that->assertEquals(1, Storage::get());
});
}

public function testInsertWithPostInsert()
{
Storage::init();
$that = $this;
$this->dbh->transactional(function($dbh) use ($that) {
$sql = new Sql($that->dbh);
$users = new Table(‘users’);
$users->postInsert(function() {Storage::increment();});

$that->assertEquals(0, Storage::get());
$actual = $sql->insert($users, array(‘uid’ => 7, ‘name’ => ‘Gonzalo’, ‘surname’ => ‘Ayuso’));
$that->assertTrue($actual);

$that->assertEquals(1, Storage::get());
});
}

public function testInsertWithPrePostInsert()
{
Storage::init();
$that = $this;
$this->dbh->transactional(function($dbh) use ($that) {
$sql = new Sql($that->dbh);
$users = new Table(‘users’);
$users->preInsert(function() {Storage::increment();});
$users->postInsert(function() {Storage::decrement();});

$that->assertEquals(0, Storage::get());
$actual = $sql->insert($users, array(‘uid’ => 7, ‘name’ => ‘Gonzalo’, ‘surname’ => ‘Ayuso’));
$that->assertTrue($actual);

$that->assertEquals(0, Storage::get());
});
}

public function testUpdateWithPrePostInsert()
{
Storage::init();
$that = $this;
$this->dbh->transactional(function($dbh) use ($that) {
$sql = new Sql($that->dbh);
$users = new Table(‘users’);
$users->preUpdate(function() {Storage::increment();});
$users->postUpdate(function() {Storage::increment();});

$that->assertEquals(0, Storage::get());
$actual = $sql->insert($users, array(‘uid’ => 7, ‘name’ => ‘Gonzalo’, ‘surname’ => ‘Ayuso’));
$that->assertTrue($actual);
$that->assertEquals(0, Storage::get());

$data = $sql->select(‘users’, array(‘uid’ => 7));
$that->assertEquals(‘Gonzalo’, $data[0][‘name’]);

$actual = $sql->update($users, array(‘name’ => ‘gonzalo’,), array(‘uid’ => 7));
$that->assertTrue($actual);
$that->assertEquals(2, Storage::get());

$data = $sql->select(‘users’, array(‘uid’ => 7));
$that->assertEquals(‘gonzalo’, $data[0][‘name’]);
});
}

public function testDeleteWithPrePostInsert()
{
Storage::init();
$that = $this;
$this->dbh->transactional(function($dbh) use ($that) {
$sql = new Sql($that->dbh);
$users = new Table(‘users’);
$users->preDelete(function() {Storage::increment();});
$users->postDelete(function() {Storage::increment();});

$that->assertEquals(0, Storage::get());
$actual = $sql->insert($users, array(‘uid’ => 7, ‘name’ => ‘Gonzalo’, ‘surname’ => ‘Ayuso’));
$that->assertTrue($actual);
$that->assertEquals(0, Storage::get());

$actual = $sql->delete($users, array(‘uid’ => 7));
$that->assertTrue($actual);
$that->assertEquals(2, Storage::get());
});
}
}
[/sourcecode]

And here the whole library:
[sourcecode language=”php”]
class Conn extends PDO
{
private $forcedRollback = false;
public function transactional(Closure $func)
{
$this->beginTransaction();
try {
$func($this);
$this->forcedRollback ? $this->rollback() : $this->commit();
} catch (Exception $e) {
$this->rollback();
throw $e;
}
}

public function forceRollback()
{
$this->forcedRollback = true;
}
}

class Table
{
private $tableName;

function __construct($tableName)
{
$this->tableName = $tableName;
}

private $cbkPostInsert;
private $cbkPostUpdate;
private $cbkPostDelete;
private $cbkPreInsert;
private $cbkPreUpdate;
private $cbkPreDelete;

public function getTableName()
{
return $this->tableName;
}

public function postInsert(Closure $func)
{
$this->cbkPostInsert = $func;
}

public function postUpdate(Closure $func)
{
$this->cbkPostUpdate = $func;
}

public function postDelete(Closure $func)
{
$this->cbkPostDelete = $func;
}

public function preInsert(Closure $func)
{
$this->cbkPreInsert = $func;
}

public function preUpdate(Closure $func)
{
$this->cbkPreUpdate = $func;
}

public function preDelete(Closure $func)
{
$this->cbkPreDelete = $func;
}

public function execPostInsert($values)
{
$func = $this->cbkPostInsert;
if ($this->cbkPostInsert instanceof Closure) $func($values);
}

public function execPostUpdate($values, $where)
{
$func = $this->cbkPostUpdate;
if ($func instanceof Closure) $func($values, $where);
}

public function execPostDelete($where)
{
$func = $this->cbkPostDelete;
if ($func instanceof Closure) $func($where);
}

public function execPreInsert($values)
{
$func = $this->cbkPreInsert;
if ($func instanceof Closure) $func($values);
}

public function execPreUpdate($values)
{
$func = $this->cbkPreUpdate;
if ($func instanceof Closure) $func($values);
}

public function execPreDelete($where)
{
$func = $this->cbkPreDelete;
if ($func instanceof Closure) $func($where);
}
}

class Sql
{
/** @var Conn */
private $dbh;
function __construct(Conn $dbh)
{
$this->dbh = $dbh;
}

public function select($table, $where)
{
$tableName = ($table instanceof Table) ? $table->getTableName() : $table;
$sql = $this->createSelect($tableName, $where);
$whereParams = $this->getWhereParameters($where);
$stmp = $this->dbh->prepare($sql);
$stmp->execute($whereParams);
return $stmp->fetchAll();
}

public function insert($table, $values)
{
$tableName = ($table instanceof Table) ? $table->getTableName() : $table;
$sql = $this->createInsert($tableName, $values);

if ($table instanceof Table) $table->execPreInsert($values);
$stmp = $this->dbh->prepare($sql);
$out = $stmp->execute($values);
if ($table instanceof Table) $table->execPostInsert($values);
return $out;
}

public function update($table, $values, $where)
{
$tableName = ($table instanceof Table) ? $table->getTableName() : $table;
$sql = $this->createUpdate($tableName, $values, $where);
$whereParams = $this->getWhereParameters($where);

if ($table instanceof Table) $table->execPreUpdate($values, $where);
$stmp = $this->dbh->prepare($sql);
$out = $stmp->execute(array_merge($values, $whereParams));
if ($table instanceof Table) $table->execPostUpdate($values, $where);
return $out;
}

public function delete($table, $where)
{
$tableName = ($table instanceof Table) ? $table->getTableName() : $table;
$sql = $this->createDelete($tableName, $where);
$whereParams = $this->getWhereParameters($where);

if ($table instanceof Table) $table->execPreDelete($where);
$stmp = $this->dbh->prepare($sql);
$out = $stmp->execute($whereParams);
if ($table instanceof Table) $table->execPostDelete($where);
return $out;
}

protected function getWhereParameters($where)
{
$whereParams = array();
foreach ($where as $key => $value) {
$whereParams[":W_{$key}"] = $value;
}
return $whereParams;
}

protected function createSelect($table, $where)
{
return "SELECT * FROM " . $table . $this->createSqlWhere($where);
}

protected function createUpdate($table, $values, $where)
{
$sqlValues = array();
foreach (array_keys($values) as $key) {
$sqlValues[] = "{$key} = :{$key}";
}
return "UPDATE {$table} SET " . implode(‘, ‘, $sqlValues) . $this->createSqlWhere($where);
}

protected function createInsert($table, $values)
{
$sqlValues = array();
foreach (array_keys($values) as $key) {
$sqlValues[] = ":{$key}";
}
return "INSERT INTO {$table} (" . implode(‘, ‘, array_keys($values)) . ") VALUES (" . implode(‘, ‘, $sqlValues) . ")";
}

protected function createDelete($table, $where)
{
return "DELETE FROM {$table}" . $this->createSqlWhere($where);
}

protected function createSqlWhere($where)
{
if (count((array) $where) == 0) return null;

$whereSql = array();
foreach ($where as $key => $value) {
$whereSql[] = "{$key} = :W_{$key}";
}
return ‘ WHERE ‘ . implode(‘ AND ‘, $whereSql);
}
}
[/sourcecode]

Strange behavior in PHP with method visibility

Normally I feel very comfortable with PHP, but not all is good. There’s some things I don’t like. One is the lack of real annotations and another one is this rare behaviour with visibility within the OO. Let me explain this a little bit.

Last week I was refactoring one old script. I removed a coupling problem with DI. Something like this:

[sourcecode language=”php”]
class AnotherClass
{
protected function foo()
{
return "bar";
}
}

class OneClass extends AnotherClass{
private $object;

public function __construct(AnotherClass $object)
{
$this->object = $object;
}

public function myFunction()
{
return $this->object->foo();
}
}

$anotherClass = new AnotherClass();
$oneClass = new OneClass($anotherClass);

echo $oneClass->myFunction();
[/sourcecode]

It works, but I realized that I didn’t need to extend OneClass with AnotherClass (due to the DI), so I removed it. Then the script crashed:
Fatal error: Call to protected method AnotherClass::foo() from context ‘OneClass’

Obviously it was due to the protected function AnotherClass::foo. But, Why it worked when I extends OneClass with AnotherClass? The visibility is the same.

I reported this “bug” to the PHP community. PHP community is great. I had an answer very quick. It was not a bug. I needed to read several times the answer to understand it but finally did it.

As someone answer me:

foo() is protected and was defined in the context of OneClass. The access is done in the context of AnotherClass. AnotherClass is a subclass of OneClass (the context where foo() was defined). Therefore access is granted

In PHP the visibility belongs to the class not to the instance of the class. I understand the reason, but my mind compute it as a bug 🙁 and it isn’t. It’s a feature.

What do you think?

Database connection pooling with PHP and React (node.php)

Last saturday I meet a new hype: “React” also known as “node.php”. Basically it’s the same idea than node.js but built with PHP instead of javascript. Twitter was on fire with this new library (at least my timeline). The next sunday was a rainy day and because of that I spent the afternoon hacking a little bit with this new library. Basically I want to create a database connection pooling. It’s one of the things that I miss in PHP. I wrote a post here some time ago with this idea with one exotic experiment building one connection pooling using gearman. Today the idea is the same but now with React. Let’s start

First of all we install React. It’s a simple process using composer.
[sourcecode language=”bash”]
% echo ‘{ "require": { "react/react": "dev-master" } }’ > composer.json
% composer install
[/sourcecode]

Now we can start with our experiment. Imagine a simple query to PostgreSql using PDO:
[sourcecode language=”sql”]
CREATE TABLE users
(
uid integer NOT NULL,
name character varying(50),
surname character varying(50),
CONSTRAINT pk_users PRIMARY KEY (uid)
)
WITH (
OIDS=FALSE
);
ALTER TABLE users OWNER TO gonzalo;

INSERT INTO users(uid, name, surname) VALUES (0, ‘Gonzalo’, ‘Ayuso’);
INSERT INTO users(uid, name, surname) VALUES (1, ‘Hans’, ‘Solo’);
INSERT INTO users(uid, name, surname) VALUES (2, ‘Luke’, ‘Skywalker’);
[/sourcecode]

[sourcecode language=”php”]
$dbh = new PDO(‘pgsql:dbname=demo;host=vmserver’, ‘gonzalo’, ‘password’);
$sql = "SELECT * FROM USERS";
$stmt = $dbh->prepare($sql);
$stmt->execute();
$data = $stmt->fetchAll();
print_r($data);
[/sourcecode]

Now we are going to use the same interface but instead of using PDO we will use one server with React:
[sourcecode language=”php”]
include "CPool.php";
define(‘NODEPHP’, ‘127.0.0.1:1337’);

$dbh = new CPool();
$sql = "SELECT * FROM USERS";
$stmt = $dbh->prepare($sql);
$stmt->execute();
$data = $stmt->fetchAll();
$stmt->closeCursor();
print_r($data);
[/sourcecode]

Our CPool library:
[sourcecode language=”php”]
class CPoolStatement
{
private $stmt;
function __construct($sql=null)
{
if (!is_null($sql)) {
$url = "http://&quot; . NODEPHP . "?" . http_build_query(array(
‘action’ => ‘prepare’,
‘sql’ => $sql
));
$this->stmt = file_get_contents($url);
}
}

public function getId()
{
return $this->stmt;
}

public function setId($id)
{
$this->stmt = $id;
}

public function execute($values=array())
{
$url = "http://&quot; . NODEPHP . "?" . http_build_query(array(
‘action’ => ‘execute’,
‘smtId’ => $this->stmt,
‘values’ => $values
));
$this->stmt = file_get_contents($url);
}

public function fetchAll()
{
$url = "http://&quot; . NODEPHP . "?" . http_build_query(array(
‘action’ => ‘fetchAll’,
‘smtId’ => $this->stmt
));
return (file_get_contents($url));
}

public function closeCursor()
{
$url = "http://&quot; . NODEPHP . "?" . http_build_query(array(
‘action’ => ‘closeCursor’,
‘smtId’ => $this->stmt
));
return (file_get_contents($url));
}
}

class CPool
{
function prepare($sql)
{
return new CPoolStatement($sql);
}
}
[/sourcecode]

We also can create one script that creates one statement
[sourcecode language=”php”]
include "CPool.php";
define(‘NODEPHP’, ‘127.0.0.1:1337’);

$dbh = new CPool();
$sql = "SELECT * FROM USERS";
$stmt = $dbh->prepare($sql);

echo $stmt->getId();
[/sourcecode]

And another script (another http request for example) to fetch the resultset. Notice that we can execute this script all the times that we want because the compiled statement persists in the node.php server (we don’t need to create it again and again within each request).

[sourcecode language=”php”]
include "CPool.php";
define(‘NODEPHP’, ‘127.0.0.1:1337’);

$stmt = new CPoolStatement();
$stmt->setId(1);

$stmt->execute();
$data = $stmt->fetchAll();
print_r($data);
[/sourcecode]

And basically that was my sunday afternoon experiment. As you can imagine the library is totally unstable. It’s only one experiment. We can add transaccions, comits, rollbacks, savepoints, … but I needed a walk and I stopped:). What do you think?

The code is available at github

Building a simple SQL wrapper with PHP

If we don’t use an ORM within our projects we need to write SQL statements by hand. I don’t mind to write SQL. It’s simple and descriptive but sometimes we like to use helpers to avoid write the same code again and again. Today we are going to create a simple library to help use to write simple SQL queries. Let’s start:

The idea is to instead of write:
[sourcecode language=”sql”]
SELECT * from users where uid=7;
[/sourcecode]

write:

[sourcecode language=”php”]
$sql->select(‘users’, array(‘uid’ => 7));
[/sourcecode]

As we all must know, the best documentation are Unit Test, so here you are the tests of the library:

[sourcecode language=”php”]
class SqlTest extends PHPUnit_Framework_TestCase
{
public function setUp()
{
$this->dbh = new Conn(‘pgsql:dbname=db;host=localhost’, ‘gonzalo’, ‘password’);
$this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->dbh->forceRollback();
}

public function testTransactions()
{

$sql = new Sql($this->dbh);
$that = $this;

$this->dbh->transactional(function($dbh) use ($sql, $that) {
$actual = $sql->insert(‘users’, array(‘uid’ => 7, ‘name’ => ‘Gonzalo’, ‘surname’ => ‘Ayuso’));
$that->assertTrue($actual);

$actual = $sql->insert(‘users’, array(‘uid’ => 8, ‘name’ => ‘Peter’, ‘surname’ => ‘Parker’));
$that->assertTrue($actual);

$data = $sql->select(‘users’, array(‘uid’ => 8));
$that->assertEquals(‘Peter’, $data[0][‘name’]);
$that->assertEquals(‘Parker’, $data[0][‘surname’]);

$sql->update(‘users’, array(‘name’ => ‘gonzalo’), array(‘uid’ => 7));

$data = $sql->select(‘users’, array(‘uid’ => 7));
$that->assertEquals(‘gonzalo’, $data[0][‘name’]);

$data = $sql->delete(‘users’, array(‘uid’ => 7));

$data = $sql->select(‘users’, array(‘uid’ => 7));
$that->assertTrue(count($data) == 0);
});
}
}
[/sourcecode]

As you can see we use DI to inject the database connection to our library. Simple isn’t it?

Here the whole library:
[sourcecode language=”php”]
class Conn extends PDO
{
private $forcedRollback = false;
public function transactional(Closure $func)
{
$this->beginTransaction();
try {
$func($this);
$this->forcedRollback ? $this->rollback() : $this->commit();
} catch (Exception $e) {
$this->rollback();
throw $e;
}
}

public function forceRollback()
{
$this->forcedRollback = true;
}
}

class Sql
{
/** @var Conn */
private $dbh;
function __construct(Conn $dbh)
{
$this->dbh = $dbh;
}

public function select($table, $where)
{
$sql = $this->createSelect($table, $where);
$whereParams = $this->getWhereParameters($where);
$stmp = $this->dbh->prepare($sql);
$stmp->execute($whereParams);
return $stmp->fetchAll();
}

public function insert($table, $values)
{
$sql = $this->createInsert($table, $values);
$stmp = $this->dbh->prepare($sql);
return $stmp->execute($values);
}

public function update($table, $values, $where)
{
$sql = $this->createUpdate($table, $values, $where);
$whereParams = $this->getWhereParameters($where);

$stmp = $this->dbh->prepare($sql);
return $stmp->execute(array_merge($values, $whereParams));
}

public function delete($table, $where)
{
$sql = $this->createDelete($table, $where);
$whereParams = $this->getWhereParameters($where);
$stmp = $this->dbh->prepare($sql);
return $stmp->execute($whereParams);
}

protected function getWhereParameters($where)
{
$whereParams = array();
foreach ($where as $key => $value) {
$whereParams[":W_{$key}"] = $value;
}
return $whereParams;
}

protected function createSelect($table, $where)
{
return "SELECT * FROM " . $table . $this->createSqlWhere($where);
}

protected function createUpdate($table, $values, $where)
{
$sqlValues = array();
foreach (array_keys($values) as $key) {
$sqlValues[] = "{$key} = :{$key}";
}
return "UPDATE {$table} SET " . implode(‘, ‘, $sqlValues) . $this->createSqlWhere($where);
}

protected function createInsert($table, $values)
{
$sqlValues = array();
foreach (array_keys($values) as $key) {
$sqlValues[] = ":{$key}";
}
return "INSERT INTO {$table} (" . implode(‘, ‘, array_keys($values)) . ") VALUES (" . implode(‘, ‘, $sqlValues) . ")";
}

protected function createDelete($table, $where)
{
return "DELETE FROM {$table}" . $this->createSqlWhere($where);
}

protected function createSqlWhere($where)
{
if (count((array) $where) == 0) return null;

$whereSql = array();
foreach ($where as $key => $value) {
$whereSql[] = "{$key} = :W_{$key}";
}
return ‘ WHERE ‘ . implode(‘ AND ‘, $whereSql);
}
}
[/sourcecode]

You can see the full code at github.

Inject dependencies via PhpDoc

Last month I attended to Codemotion conference. I was listening to a talk about Java and I saw the “@inject” decorator. I must admit I switched off my mind from the conference and I started to take notes in my notebook. The idea is to implement something similar in PHP. It’s a pity we don’t have real decorators in PHP. I really miss them. We need to use PhpDoc. It’s not the same than real decorators in other programming languages. That’s my prototype. Let’s go.

Imagine this simple class:
[sourcecode language=”php”]
class User
{
private $db;

public function getInfo($uid)
{
$sql = "select * from users where uid=:UID";
$stmp = $this->db->prepare($sql);
$stmp->execute(array(‘UID’ => $uid));
return $stmp->fetchAll();
}

public function getDb()
{
return $this->db;
}
}
[/sourcecode]

It doesn’t work. Private property $db must be an instance of PDO object. We can solve it with dependency injection:

[sourcecode language=”php”]
class User
{
private $db;
public function __construct(PDO $db)
{
$this->db = $db;
}

public function getInfo($uid)
{
$sql = "select * from users where uid=:UID";
$stmp = $this->db->prepare($sql);
$stmp->execute(array(‘UID’ => $uid));
return $stmp->fetchAll();
}
}
[/sourcecode]

Now it works but we are going to create a simple PDO Wrapper to obtain the PDO connection.
[sourcecode language=”php”]
class DbConf
{
const DB1 = ‘db1’;

private static $conf = array(
self::DB1 => array(
‘dsn’ => ‘pgsql:dbname=db;host=localhost’,
‘user’ => ‘gonzalo’,
‘pass’ => ‘password’,
)
);

public static function getConf($key)
{
return self::$conf[$key];
}
}

class Db extends PDO
{
private static $dbInstances = array();

/**
* @static
* @param string $key
* @return PDO
*/
static function getDb($key)
{
if (!isset($dbInstances[$key])) {
$dbConf = DbConf::getConf($key);
$dbInstances[$key] = new PDO($dbConf[‘dsn’], $dbConf[‘user’], $dbConf[‘pass’]);
}
return $dbInstances[$key];
}
}
[/sourcecode]

I like to use this kind of classes because I normally work with different databases and I need to use different connection depending on the SQL. It helps me to mock the database connection within the different environments (development, production, QA). Now We can use our simple class:

[sourcecode language=”php”]
$user = new User(Db::getDb(DbConf::DB1));
print_r($user->getInfo(4));
[/sourcecode]

The idea is to change the class into something like this:

[sourcecode language=”php”]
class User extends DocInject
{
/**
* @inject Db::getDb(DbConf::DB1)
* @var PDO
*/
private $db;

public function getInfo($uid)
{
$sql = "select * from users where uid=:UID";
$stmp = $this->db->prepare($sql);
$stmp->execute(array(‘UID’ => $uid));
return $stmp->fetchAll();
}
}
[/sourcecode]

Now we are going to inject the PDO connection to $db private property in the constructor:

[sourcecode language=”php”]
class DocInject
{
public function __construct()
{
$reflection = new ReflectionClass($this);
foreach ($reflection->getProperties() as $property) {
/** @var ReflectionProperty $property */
$docComment = $property->getDocComment();
$docComment = preg_replace(‘#[ \t]*(?:\/\*\*|\*\/|\*)?[ ]{0,1}(.*)?#’, ‘$1’, $docComment);
$docComment = trim(str_replace(‘*/’, null, $docComment));
foreach (explode("\n", $docComment) as $item) {
if (strpos($item, ‘@inject’) !== false) {
$inject = trim(str_replace(‘@inject’, null, $item));
$value = null;
eval("\$value = {$inject};"); // yes, eval. uggly, isnt’t?
$property->setAccessible(true);
$property->setValue($this, $value);
}
}
}
}
}
[/sourcecode]
If you have read “Clean Code” (if not, you must do it) you noticed that uncle Bob doesn’t like this class. The method is too long, so we are going to refactor a little bit.

[sourcecode language=”php”]
class DocInject
{
public function __construct()
{
$reflection = new ReflectionClass($this);
foreach ($reflection->getProperties() as $property) {
$this->processProperty($property);
}
}

private function processProperty(ReflectionProperty $property)
{
$docComment = $this->cleanPhpDoc($property->getDocComment());
foreach (explode("\n", $docComment) as $item) {
if ($this->existsInjectDecorator($item)) {
$this->performDependencyInjection($property, $item);
}
}
}

private function cleanPhpDoc($docComment)
{
$docComment = preg_replace(‘#[ \t]*(?:\/\*\*|\*\/|\*)?[ ]{0,1}(.*)?#’, ‘$1’, $docComment);
$docComment = trim(str_replace(‘*/’, null, $docComment));
return $docComment;
}

private function existsInjectDecorator($item)
{
return strpos($item, ‘@inject’) !== false;
}

private function performDependencyInjection(ReflectionProperty $property, $item)
{
$injectString = $this->removeDecoratorFromPhpDoc($item);
$value = $this->compileInjectString($injectString);
$this->injectValueIntoProperty($property, $value);
}

private function removeDecoratorFromPhpDoc($item)
{
return trim(str_replace(‘@inject’, null, $item));
}

private function compileInjectString($injectString)
{
$value = null;
eval("\$value = {$injectString};"); // yes, eval. uggly, isnt’t?
return $value;
}

private function injectValueIntoProperty(ReflectionProperty $property, $value)
{
$property->setAccessible(true);
$property->setValue($this, $value);
}
}
[/sourcecode]

So now we don’t need to pass the new instance of PDO connection in the constructor with DI:
[sourcecode language=”php”]
$user = new User();
print_r($user->getInfo(4));
[/sourcecode]

It works but there’s something that I don’t like. We need to extend our User class with DocInject. I like plain classes. Because of that we are going to use the new feature of PHP5.4: traits

Instead of extend our class with DocInject we are going to create:
[sourcecode language=”php”]
trait DocInject
{
public function parseDocInject()
{
$reflection = new ReflectionClass($this);
foreach ($reflection->getProperties() as $property) {
$this->processProperty($property);
}
}

private function processProperty(ReflectionProperty $property)
{
$docComment = $this->cleanPhpDoc($property->getDocComment());
foreach (explode("\n", $docComment) as $item) {
if ($this->existsInjectDecorator($item)) {
$this->performDependencyInjection($property, $item);
}
}
}

private function cleanPhpDoc($docComment)
{
$docComment = preg_replace(‘#[ \t]*(?:\/\*\*|\*\/|\*)?[ ]{0,1}(.*)?#’, ‘$1’, $docComment);
$docComment = trim(str_replace(‘*/’, null, $docComment));
return $docComment;
}

private function existsInjectDecorator($item)
{
return strpos($item, ‘@inject’) !== false;
}

private function performDependencyInjection(ReflectionProperty $property, $item)
{
$injectString = $this->removeDecoratorFromPhpDoc($item);
$value = $this->compileInjectString($injectString);
$this->injectValueIntoProperty($property, $value);
}

private function removeDecoratorFromPhpDoc($item)
{
return trim(str_replace(‘@inject’, null, $item));
}

private function compileInjectString($injectString)
{
$value = null;
eval("\$value = {$injectString};"); // yes, eval. uggly, isnt’t?
return $value;
}

private function injectValueIntoProperty(ReflectionProperty $property, $value)
{
$property->setAccessible(true);
$property->setValue($this, $value);
}
}
[/sourcecode]

And now:

[sourcecode language=”php”]
class User
{
use DocInject;

public function __construct()
{
$this->parseDocInject();
}

/**
* @inject Db::getDb(DbConf::DB1)
* @var PDO
*/
private $db;

public function getInfo($uid)
{
$sql = "select * from users where uid=:UID";
$stmp = $this->db->prepare($sql);
$stmp->execute(array(‘UID’ => $uid));
return $stmp->fetchAll();
}
}
[/sourcecode]

This implementation has a little problem. If our class User needs a constructor we have a problem. As far as I know we cannot use parent::__construct() with a trait. We can solve this problem changing the code a little bit:

[sourcecode language=”php”]
class User
{
use DocInject {parseDocInject as __construct;}

/**
* @inject Db::getDb(DbConf::DB1)
* @var PDO
*/
private $db;

public function getInfo($uid)
{
$sql = "select * from users where uid=:UID";
$stmp = $this->db->prepare($sql);
$stmp->execute(array(‘UID’ => $uid));
return $stmp->fetchAll();
}
}
[/sourcecode]

A simple unit test
[sourcecode language=”php”]
public function testSimple()
{
$user = new User();
$this->assertTrue(count($user->getInfo(4)) > 0);
}
[/sourcecode]

If we use different DbConf file for each environment we can easily use one database or another without changing any line of code.

And that’s all. What do you think?

(Files available as gist here and here)

How to use eval() without using eval() in PHP

Yes I know. Eval() is evil. If our answer is to use eval() function, we are probably asking the wrong question. When we see an eval() function all our coding smell’s red lights start flashing inside our mind. Definitely it’s a bad practice.

But last week I was thinking about it. How can I eval raw PHP code without using the eval function, and I will show you my outcomes.

Imagine this simple script
[sourcecode language=”php”]
<?php
error_reporting(-1);

class Foo
{
private $name;
public function __construct($name)
{
$this->name = $name;
}

public function hello()
{
return $this->name;
}
}

$serializedOutput = null;
foreach (range(1, 100000) as $i) {
$object = new Foo("name" . $i);
$out[] = $object->hello();
}

$serializedOutput = serialize($out);

echo strlen($serializedOutput);
[/sourcecode]

Now we are going to the same using eval function. Imagine for example that we are using an online PHP interpreter (yes, it’s hard to find examples to use eval()).

[sourcecode language=”php”]
<?php
error_reporting(-1);

// Our PHP code inside a variable
$phpCode = ‘
class Foo
{
private $name;
public function __construct($name)
{
$this->name = $name;
}

public function hello()
{
return $this->name;
}
}

$serializedOutput = null;
foreach (range(1, 100000) as $i) {
$object = new Foo("name" . $i);
$out[] = $object->hello();
}
$serializedOutput = serialize($out);
‘;
// end of variable
eval($phpCode);

echo strlen($serializedOutput);
[/sourcecode]

Our ugly “eval” version does the same than the original one. Even the performance is almost the same. More or less the same memory usage and speed. The challenge now is to do the same but without using eval().

My idea is simple. Create a temporary file with the PHP source code, include this file with the standard PHP’s include functions and destroy the temporary file. Here is the code snippet:

[sourcecode language=”php”]
<?php
error_reporting(-1);

// Our PHP code inside a variable
$phpCode = ‘
class Foo
{
private $name;
public function __construct($name)
{
$this->name = $name;
}

public function hello()
{
return $this->name;
}
}

$serializedOutput = null;
foreach (range(1, 100000) as $i) {
$object = new Foo("name" . $i);
$out[] = $object->hello();
}
$serializedOutput = serialize($out);
‘;
// end of variable
function fakeEval($phpCode) {
$tmpfname = tempnam("/tmp", "fakeEval");
$handle = fopen($tmpfname, "w+");
fwrite($handle, "<?php\n" . $phpCode);
fclose($handle);
include $tmpfname;
unlink($tmpfname);
return get_defined_vars();
}
extract(fakeEval($phpCode));
echo strlen($serializedOutput);
[/sourcecode]

This fake-eval have similar performance than eval version. Maybe a bit worse, probably because of the creation of the temp file, but almost inappreciable.

Maybe is not very useful script and, of course I strongly recommend the first version (without eval and fake-eval) but, what do you think?

How to protect from SQL Injection with PHP

Security is a part of our work as developers. We need to ensure our applications against malicious attacks. SQL Injection is one of the most common possible attacks. Basically SQL Injection is one kind of attack that happens when someone injects SQL statements in our application. You can find a lot of info about SQL Injection attack. Basically you need to follow the security golden rule

Filter input
Escape output

If you work with PHP problably you work with PDO Database abstraction layer.
Let’s prepare our database for the examples (I work with PostgreSQL):

[sourcecode language=”sql”]
CREATE TABLE users
(
uid integer NOT NULL,
name character varying(50),
surname character varying(50),
CONSTRAINT pk_users PRIMARY KEY (uid)
)
WITH (
OIDS=FALSE
);
ALTER TABLE users OWNER TO gonzalo;

INSERT INTO users(uid, name, surname) VALUES (0, ‘Gonzalo’, ‘Ayuso’);
INSERT INTO users(uid, name, surname) VALUES (1, ‘Hans’, ‘Solo’);
INSERT INTO users(uid, name, surname) VALUES (2, ‘Luke’, ‘Skywalker’);
[/sourcecode]

OK our database is ready. Now let create a simple query
[sourcecode language=”php”]
$dbh = new PDO(‘pgsql:dbname=db;host=localhost’, ‘gonzalo’, ‘password’);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$stmt = $dbh->prepare(‘select uid, name, surname from users where uid=:ID’);
$stmt->execute(array(‘ID’ => 0));
$data = $stmt->fetchAll();
[/sourcecode]
It works. We are using bind parameters, so we need to prepare one statement, execute and fetch the recordset. The use of prepared statements is strongly recommended. We can also use query() function:

[sourcecode language=”php”]
$dbh = new PDO(‘pgsql:dbname=db;host=localhost’, ‘gonzalo’, ‘password’);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$uid = 0;
$stmt = $dbh->query("select uid, name, surname from users where uid={$uid}");
$data = $stmt->fetchAll();
[/sourcecode]

But what happens if $id came from the request and it’s not propertly escaped
[sourcecode language=”php”]
$dbh = new PDO(‘pgsql:dbname=db;host=localhost’, ‘gonzalo’, ‘password’);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$uid = "0; drop table users;";
$stmt = $dbh->query("select uid, name, surname from users where uid={$uid}");
$data = $stmt->fetchAll();
[/sourcecode]

basically nothing: SQLSTATE[42601]: Syntax error. That’s because is not allowed to use two prepared statements in a single statement.

If we use an insert:

[sourcecode language=”php”]
$dbh = new PDO(‘pgsql:dbname=db;host=localhost’, ‘gonzalo’, ‘password’);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$uid = 20;
$name = ‘Gonzalo’;
$surname = "Ayuso’); drop table users; select 1 where (‘1’ = ‘1";

$count = $dbh->exec("INSERT INTO users(uid, name, surname) VALUES ({$uid}, ‘{$name}’, ‘{$surname}’)");
[/sourcecode]

Now we have a problem. Our user table will be deleted. Why? That’s because of the user we are using to connect to the database. It’s important especially at production servers.
It’s very important not to use a database superuser in production. Superusers are very comfortable in our development servers, because you don’t need to grant privileges to every tables but if you forget this issue in production you could have Sql-Injection problems. The solution is very simple:

[sourcecode language=”sql”]
GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE users TO gonzalo2;
[/sourcecode]

And now
[sourcecode language=”php”]
$dbh = new PDO(‘pgsql:dbname=db;host=localhost’, ‘gonzalo2’, ‘password’);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$uid = 20;
$name = ‘Gonzalo’;
$surname = "Ayuso’); drop table users; select 1 where (‘1’ = ‘1";

$count = $dbh->exec("INSERT INTO users(uid, name, surname) VALUES ({$uid}, ‘{$name}’, ‘{$surname}’)");
[/sourcecode]

Now we are safe, at least with this possible attack.
Sumarizing:

  • Filter input
  • Escape output
  • Take care about the database users. Don’t use one user that it allowed to perform “not-allowed” operations within our application. It sounds like a pun but is important.

Checking the performance of PHP exceptions

Sometimes we use exceptions to manage the flow of our scripts. I imagine that the use of exceptions must have a performance lack. Because of that I will perform a small benchmark to test the performance of one simple script throwing exceptions and without them. Let’s start:

First a silly script to find even numbers (please don’t use it it’s only for the benchmanrk 🙂 )
[sourcecode language=”php”]
error_reporting(-1);
$time = microtime(TRUE);
$mem = memory_get_usage();

$even = $odd = array();
foreach (range(1, 100000) as $i) {
try {
if ($i % 2 == 0) {
throw new Exception("even number");
} else {
$odd[] = $i;
}
} catch (Exception $e) {
$even[] = $i;
}
}
echo "odds: " . count($odd) . ", evens " . count($even);
print_r(array(‘memory’ => (memory_get_usage() – $mem) / (1024 * 1024), ‘microtime’ => microtime(TRUE) – $time));
[/sourcecode]

And now the same script without exceptions.

[sourcecode language=”php”]
error_reporting(-1);
$time = microtime(TRUE);
$mem = memory_get_usage();

$even = $odd = array();
foreach (range(1, 100000) as $i) {
if ($i % 2 == 0) {
$even[] = $i;
} else {
$odd[] = $i;
}
}

echo "odd: " . count($odd) . ", evens " . count($even);
print_r(array(‘memory’ => (memory_get_usage() – $mem) / (1024 * 1024), ‘microtime’ => microtime(TRUE) – $time));
[/sourcecode]

The outcomes:
with exceptions
memory: 10.420181274414
microtime: 1.1479668617249 0.19249302864075 (without xdebug)

without exceptions
memory: 10.418941497803
microtime: 0.14752888679505 0.1234929561615

As we can see the use of memory is almost the same and ten times faster without exceptions.

I have done this test using a VM box with 512MB of memory and PHP 5.3.
Now we are going to do the same test with a similar host. The same configuration but PHP 5.4 instead of 5.3

PHP 5.4:
with exceptions
memory: 7.367259979248
microtime: 0.1864490332

without exceptions
memory: 7.3669052124023
microtime: 0.089046955108643

I’m really impressed with the outcomes. The use of memory here with PHP 5.4 is much better now and the execution time better too (ten times faster).

According to the outcomes my conclusion is that the use of exceptions in the flow of our scripts is not as bad as I supposed. OK in this example the use of exceptions is not a good idea, but in another complex script exceptions are really useful. We also must take into account the tests are iterations over 100000 to maximize the differences. So I will keep on using exceptions. This kind of micro-optimization not seems to be really useful. What do you think?