Category Archives: PHP

Symfony2 & Doctrine: Custom Entity Repositories

In Symfony2, we can easily map a custom repository class for an entity. This allows us to extend the functionality of the repository. For example, we can add custom methods for even more customizable data retrieval. Without any ado, let’s jump into codes.

First, create the class which will act as the repository. It must extend “Doctrine\ORM\EntityRepository”. Here, we’re creating a repository for “User” objects inside “WeCodePHP\HomeBundle\Entity”. You can get the entity manager using “$this->getEntityManager()” inside a method.

Now, in the original entity, we need to define which class should be used as the repository class. We do that like this:

The repositoryClass tells Symfony2 about the custom repository.

Now, we can call our custom methods with ease:

Custom repository is what we very often do in models in other frameworks.

Using annotations in PHP with Doctrine Annotation Reader

Ever since I have seen the use of Annotations in Symfony2 framework, I have been looking for a way to use them in my own projects as well. After looking into the Symfony2′s source code, I noticed that they are indirectly using Doctrine’s Annotation Reader. Reading annotation from your own class is pretty easy. PHP includes the docblocks in the different reflection objects. You just have to read the docblock and parse it. Doctrine does it pretty nicely. Let’s see an example!

To get started, you first need to install doctrine-common package. I recommend you install using composer. Here’s my composer.json for the project:

Now, we need to define the annotation classes. Every annotation you use should have a class with the same name. Doctrine Annotation Reader will map those annotations with these classes and pass the values to the public properties of these classes.

In our example, we shall use one annotation class named – “AnnotatedDescription”. It can be directly passed a value, like:

or in an associative fashion -

We shall allow two keys – “desc” and “type” in these example. But feel free to add your own. Again, in real life, I would declare separate classes for capturing single value and key-value pairs.

Lets declare the AnnotatedDescription class in annotations.php:

Note that, the $value property is used for annotations which accept just a value. For key value pairs, we must declare properties with the key names. You *must* annotate the classes with @Annotation to let Doctrine’s Annotation Reader know that this class should be used for annotations mapping.

Now, lets see the parser file (parse_annotations.php):

The code is pretty much self explanatory. We instantiate “Doctrine\Common\Annotations\AnnotationReader” and use it’s different methods to get the annotations. You might want to study the source code of “Doctrine\Common\Annotations” namespace for even detailed usages.

Note that we must pass reflection objects for the class, properties and methods (eg. ReflectionClass, ReflectionObject, ReflectionProperty, ReflectionMethod). For the properties , instead of directly constructing ReflectionProperty object, we can use getProperty() on a ReflectionObject object in runtime.

Debugging with XDebug and PhpStorm on MacOS X

In an earlier post I demonstrated how to install PHP5.4 using brew. Today, I required xdebug for debugging purposes and found it quite easy to install via homebrew.

Install XDebug for PHP
It’s as simple as issuing the command:

Enabling XDebug
I had to add the extension to my php.ini file:

Follow the output of the brew info output of the package you installed (either php53 or php54):

To enable remote debugging, I also added these lines:

Debugging Web Applications
In the run configuration, add “Web Application” type. Configure the server and path as usual. When setup, you shall notice the debug button is active. Setup some break points and hit the debug button.

You can also use the “Listen PHP Debug Connection” option along with some xdebug bookmarklet for quick debugging.

Debugging Command Line Scripts
To debug command line scripts, first issue this command on terminal:

PS: I added the line to my ~/.bash_profile so that I don’t have to type it every time I login to bash shell.

Turn on incoming connections by clicking the “Start Listen PHP Debug Connection” button. Set some break points and then run the script from command line.

Composer & Packagist: Painless Dependency Manager for PHP

URLs:
Packagist: http://packagist.org/
Composer: http://getcomposer.org/

Composer is a painless dependency manager for PHP. If you have used the conventional PEAR packaging system, you have probably felt the pain already. Composer came to our rescue.

Getting Started with Composer:
Follow this link to get yourself introduced with Composer: http://getcomposer.org/doc/00-intro.md

In short, you declare the dependency of your project in a file named “composer.json”. Then run “composer install” on the terminal. Composer will install the dependencies and provide you a single autoloader file which you can require in your project and start using the libraries/tools etc.

I recommend installing composer into your own “~/bin” so that you can quickly access it from any place. Use these commands to achieve that:

Of course, I assumed that you already have a “~/bin” directory created and the path is in your bash profile or bash rc.

Packagist: Creating packages for Composer
(1) You must have a public repository of codes to prepare a package for packagist. The code repo should be in Subversion, Git or Mercurial.

(2) Create a composer.json in your package’s root directory. It is a good idea to use:

The prompt will help you get started with a basic skeleton.

(3) Add more metadata to the package by adding different fields to the composer.json file. You can read about all the available fields here: http://getcomposer.org/doc/04-schema.md

If your package depends on other packages, do mention them on the file. Also if your package needs certain PHP extension, use “ext-*” format. Like – “ext-apc” for apc extension, “ext-curl” for curl etc.

Do not forget to use the autoload feature. Define your PSR-0 or conventional autoloading pattern so that your package can be easily used with the Composer autoloader. Look into the “autoload” part of the schema for more details.

(4) After you have finished editing the composer.json file, validate it by running:

This is step is very important. If you have any error in the json document, packagist will not be able to parse your package. For now, there is no notification system for such failures. So you better validate before you publish the codes.

(5) Create an account, login to packagist.org and submit your package. Packagist allows convenient hooks for auto updating to your recent branches.

(6) Package versioning is dependent on the tags of CVS. Name your tags in “X.Y.Z” or “vX.Y.Z” format. Eg. “1.0.3″ or “v1.0.3″.

Demo:
You might want to examine these works for digging deeper into composer and packagist -

PhpTube Package: http://packagist.org/packages/masnun/phptube
Github Repository: https://github.com/masnun/phptube

Mac OS X Lion: Homebrew, PHP54, MySQL and PEAR

In one of my old posts, I noted short documentation on how to get started with the AMP stack on Mac OS X Lion. In that setup, I was using the default PHP and downloaded MySQL from the mysql website. In this post, I am going to describe how I used homebrew to setup my AMP environment with ease!

The Homebrew Magic
Homebrew is a cool tool for Mac OS users. Written in Ruby, this beautiful tool works as a package manager for Mac OS. Unlike Mac Ports or Fink, homebrew takes less space, uses the default os x tools to compile everything to a custom location. This makes life suck less and clutter free!

To install PHP 5.4 branch using homebrew, just issue this command:

PS: If you want to customize the installation (like installing the mysql module by default) add necessary configuration options. Using the “bash-completion” formula from brew, you can hit tabs to see available installation options.

To view information on your PHP 5.4 installation via brew, type in:

Seperate MySQL Installation: Where is the ctl?
I have installed MySQL separately. I added the mysql and mysqldmin to my bash_profile like this:

And to start/stop/restart mysql server, I added:

That allows me to do:

Using PEAR
Homebrew installs all the PEAR packages to “/usr/local/Cellar/php54/5.4.3/lib/php”. So, I added it to my php include_path.

For PEAR to work correctly, we need sudo. If there are tools involved in the pear setup which can be run from command line (eg. phpunit), the binary files are stored in: “/usr/local/Cellar/php54/5.4.3/bin”.

I added the above path to my .bash_profile for convenience :)

Getting started with AMP stack on Mac OS X Lion

The other day, I got myself a Macbook Pro which runs OS X Lion. Coming from the Linux world where everything is available at finger tips via package managers, I was at first lost. I tried MAMP and Zend Server CE. I had some issues with Zend Server CE and custom virtual hosts – mostly because I couldn’t figure out which bits to be changed. MAMP worked out pretty well. But I wanted to use the native builds of the AMP stack. I know about macports and homebrew but wanted to do things myself!

(1) Mac OS X ships with built in apache. I enabled “Web Sharing” from System Preference > Sharing. It turned on viewing of my ~/Sites directory at http://localhost/~masnun/. It works but not pretty helpful.

(2) I edited /etc/apache2/httpd.conf to change the document root to ~/Sites. Now I could see my home page on localhost.

(3) I tried creating virtual hosts at ~/VirtualHosts – this worked with MAMP but with the built in Apache, it can not load the virtualhosts from that location because of permission issues. So instead, I reinstated the default location for vhosts inside the “extra” directory. I appended all my virtualhosts in one file. It works!

(4) “NameVirtualHosts *” and a separate virtual host for localhost is must.

(5) Mac OS X has a built in PHP. I just created the default php configuration file at /etc/php.ini

(6) I downloaded MySQL from their website. Installed the packages and imported my existing databases.

(7) PHP by default expects the mysql unix socket to be in /var/mysql/mysql.sock but the package from mysql creates the socket at /tmp/mysql.sock. So I had to edit the socket for mysql, pdo-mysql and mysqli. I needed to change them all because WP uses mysql, phpmyadmin uses mysqli and ZF uses pdo.

(8) I ran the pear installer (as a phar file inside /usr/lib/php) to install pear and pecl.

(9) To install mcrypt extension, I downloaded libmcrypt and source of PHP 5.3.10. I changed directory to PHP’s mcrypt extension directory. Ran “phpize”, “make” and “sudo make install”. Copied the generated extension to my custom extensions directory.

(10) Restarted apache at every step. It’s now working fine :)

Running PHPUnit on Git hook

I use Git and I love Git! I knew about Git hooks but never used in real life. So today I decided to get my hands dirty with Git hooks. I had a feeling it’d be awesome if I could use the “pre-commit” hook to do some routine processing before the changes are committed. I had two things in mind: 1) Unit Testing with PHPUnit or 2) Generating documentation using DocBlox. I chose Unit testing favouring simplicity.

Summary: I have a git repo for my PHP project. I have written some unit tests for the project and I want to run an automated unit test before changes are committed. If the unit tests succeed, the changes will be committed, if one of the tests fails, the commit will not proceed. This will ensure that I am always committing *working* codes to my Git repo.

Understanding Git Hooks
Git hooks are nothing but executable scripts which are run by Git on special events. If the hook script returns an exit code of 0, Git continues with whatever it was doing. For any non zero exit code, Git halts the operation. It’s that simple!

Git hooks are stored in the “.git/hooks” directory of a git repo. There are some samples already generated for us to check out! The script should be named with the hook, that is for the “pre-commit” hook the file name should also be “pre-commit”.

My Lame Unit Test
To begin with, we need at least one test case. So I wrote this really lame unit test and saved it as “Mytest.php”

Try running the script with PHPUnit like this:

Output:

Okay, so we have a valid unit test that passes. Now let’s add a Git pre-commit hook to run this unit test before commit is made.

Setting Up Git Hook
Assuming that your project is already under Git DVCS, navigate to .git/hooks and create a file named “pre-commit” with the following contents:

PS: The pre-commit script is a modified version of this nice Gist: https://gist.github.com/975252

Make the “pre-commit” file executable by issuing this command:

NB: This is important that you make the script executable otherwise it will not function as a hook.

Making a Commit
We shall create some file or make some changes and try to commit. In my case, I just added the “Mytest.php” file and tried to commit. Here’s the output:

Aha! All tests passed and the commit was made. Now let’s force the unit test to fail. Change the unit test to look like this:

And let’s commit now:

Compare the output with previous output. There is nothing similar to:

The commit was not made because the test failed. So, it worked! :D

I am really loving what it is going to offer me! I shall be writing tests for most of my projects so I never unintentionally break something in a commit. Unit testing is just one type of validation, I believe we could use lots of others (eg. PHP Code Sniffer) :)