react/zmq installation error on PHP 5.4 with composer

Last week I upgraded my PHP to 5.4 on my mac. It was not that bad, but I am starting to pay little by little.
I am using Ratchet for a websocket and for pushing I was using 0MQ.
My composer.json looks

....
    "require": 
        "cboden/Ratchet": "0.3.*",
		"react/zmq": "dev-master"
    }
...

Then I do composer install, it was complaining zmq is not found in the system.
I had zmq already but it is on the php5.3 default directory. And I can’t use the zmq.so file I compiled b/c i am using 5.4 now.
Here is the fix:
Go and grab the git clone from github

git clone git://github.com/mkoppanen/php-zmq.git

for further ways checkout this
Then

cd php-zmq

Then do the following

phpize

Make sure you run the correct phpize in this case. If you are upgrading from 5.3 and still you have the old version sitting around on your machine, phphize will take the older one by default.
My new php 5.4’s one is in /opt/local/bin/phpize54. So make sure you are running the phpize with the new one.
One easy thing to do would be to symlink the old phpize with the new one like:

sudo ln -s new/phpize/path old/phpize/location/phpize

Backing to the topic,
Then do the configure, being inside the php-zmq folder, as follows

./configure --with-php-config=/opt/local/bin/php-config54

make sure to replace the value of –with-php-config with your proper php-config path

if you don’t have the packageconfig, you will have an error requesting for that and you can install it from macport – if you are using mac as follows:

sudo port install pkgconfig

Just search for pkgconfig for others distros you have and it should not be that difficult ..
once you do that install it by

make && make install

Hollla..
the compiled file should be inside the modules directory.
After this, copy that file into the php executables folder and add extention=zmq.so into your php.ini

Now you can do the composer install and it should install it..

Apache not executing PHP code – just renders the as it is

This is the issue when you are having a fresh install of apache usually.
You need to tell apache should handle the extensions so that it could process them accordingly.
On you apache path, go to the config and open the httpd.conf file
and add the following

AddType application/x-httpd-php .php

Also, make sure the Module for php is installed as well..
in your httpd.conf file, search for:

#LoadModule php5_module libexec/apache2/libphp5.so

and, of course, uncomment that to enable php.

Running a single PhpUnit test

Well, we all love tests :). There are times we would like to run a single test that has failed so that we can fix or look at it thoroughly.
The problem, when you are running

phpunit -c /testFolder..

All tests would run.
The fix..
Let’s assume you have this particular test in one of your test files

public function testPhpIsAwesomeOrNot(){
}

All you have to do is to add the group annotation above the function


/**
 * @group awesome
 */
public function testPhpIsAwesomeOrNot(){}

then run it with –group
like
phpunit -c /testfolder –group awesome

the requested PHP extension mongo is missing from your system.

Got this error when trying to add the mongodb stuff your php project – specially using composer then here is how to solve it.

The first thing is you have to add the mongodb driver to php.

You might need PEAR on your system. Adding pear to your system is relatively easy and google can help on that.

Then do the following on your terminal

sudo pecl install mongo
pecl install mongo

The last lines of successful installation would tell where the installation has occurred and some more important information.

Now you need to add the mongo.so to the php.ini

if you don’t know where you have php.ini run (on ubuntu)

locate php.ini

then run

echo "extension=mongo.so" >> path-to-php.ini

Installing PEAR in Mac OSX

It looks the days of PEAR are somehow covered by the era of composer. But, still there might be things we will depend on PEAR, hence we have to install it.

Are you on Mac OSX and wants to install PEAR.. follow these simple steps and you will nail it

1. download the phar file from go-pear.phar

curl -O http://pear.php.net/go-pear.phar

2. Then run the phar file

sudo php go-pear.phar

In some cases, you might want to run it with -d detect_unicode=0 option
3. You will be provided with option that would look like the following:

1. Installation base ($prefix)                   : /Users/gullele/pear
 2. Temporary directory for processing            : /tmp/pear/install
 3. Temporary directory for downloads             : /tmp/pear/install
 4. Binaries directory                            : /Users/gullele/pear/bin
 5. PHP code directory ($php_dir)                 : /Users/gullele/pear/share/pear
 6. Documentation directory                       : /Users/gullele/pear/docs
 7. Data directory                                : /Users/gullele/pear/data
 8. User-modifiable configuration files directory : /Users/gullele/pear/cfg
 9. Public Web Files directory                    : /Users/gullele/pear/www
10. Tests directory                               : /Users/gullele/pear/tests
11. Name of configuration file                    : /Users/gullele/.pearrc

Select 1 and enter where you would want to put the installation. In my case, I put it to the common installation directory /usr/local/pear

4. After that, you will have this options to choose:

1. Installation base ($prefix)                   : /usr/local/pear
 2. Temporary directory for processing            : /tmp/pear/install
 3. Temporary directory for downloads             : /tmp/pear/install
 4. Binaries directory                            : /usr/local/pear/bin
 5. PHP code directory ($php_dir)                 : /usr/local/pear/share/pear
 6. Documentation directory                       : /usr/local/pear/docs
 7. Data directory                                : /usr/local/pear/data
 8. User-modifiable configuration files directory : /usr/local/pear/cfg
 9. Public Web Files directory                    : /usr/local/pear/www
10. Tests directory                               : /usr/local/pear/tests
11. Name of configuration file                    : /Users/gullele/.pearrc

Ideally, you can put the binaries anywhere you want but you would have to add it to the PATH to be able to access it from anywhere. But if you put it inside /user/local/bin that would automatically be taken care of – do that and that would pretty much take you to the end of pear installation.

Happey PEARing

file upload

multiple file upload in Symfony2 example

Multiple File Upload in Symfony framework

I spent decent amount of time to put together the multiple file upload in symfony.

It is not that difficult actually but the problem is there is no direct/easy documentation or tutorial on it.

On the form type where you would build the form, have the files with the type of collection and make its type a file entity. In this case there would be two file types by default.

    public function buildForm(FormBuilderInterface $builder, array $options) 
    {
        /*
         * The file does not need to be added as "file" because it is referred
         * in the validation for File and SF will automatically know it is file.
         */
        return $builder
                ->add("files", 'collection', array(
		    'type'=>new FileType(),
		    'allow_add'=>true,
		    'data'=>array(new BundleEntityFile(),
		    new BundleEntityFile())
		))
                ->add('save', 'submit');
    }

    public function getName()
    {
        return "files";
    }
}

The trick is on adding the files as collection. Initially, we have two file inputs and their type being FileType.

The allow_add is important to be able to add files through javascript.

The javascript would look like:

/*Handling multiple picture upload*/
$('#add_pictures').click(function(){
    var total_files=$("#member_pictures_container li").length;
    var file_label=document.createElement("label");
    file_label.innerHTML="File";
    file_label.for="PhotoAndDescription_files_"+total_files;
    var div_file=document.createElement("div");    
    div_file.appendChild(file_label);
    var picture= document.createElement('input');
    picture.name="PhotoAndDescription[files]["+total_files+"][file]";
    picture.type="file";
    picture.id="PhotoAndDescripton_files_"+total_files;
    div_file.appendChild(picture);
    div_container=document.createElement('div');
    div_container.id="PhotoAndDescription_files_"+total_files;
    div_container.appendChild(div_file);
    var list_element=document.createElement('li');
    list_element.appendChild(div_container);
    $('#member_pictures_container').append(list_element);
});

FileType would look like:

class FileType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        return $builder->add("file", "file");
    }

    public function getName()
    {
        return "filetype";
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class'=>'BundleEntityFile',
            'csrf_protection'=>true,
            'csrf_field_name'=>'_token',
            'intention'=>'file'
        ));
    }
}

 

And the twig file would look like this one

{{form_start(form)}}
    {{ form_errors(form) }}
    {{ form_widget(form.about_member) }}
    • {% for file in form.files %}

 

  • {{ form_errors(file) }} {{ form_widget(file) }}

 

 

{% endfor %} {{form_end(form)}}

Pretty much this will take care of the multiple file handling in symfony2. As I mentioned earlier, it is not that difficult but the lack of documentation has made it so..

Do you know what to check to deploy Symfony app?

What is POST and HTTP-RAW-POST and php input has to do with enctype? Find out here

Sorting array by two fields in PHP

assume you have the following array:

$arr=array(
	array('field1'=>108, 'field2'=>'some'),
	array('field1'=>200, 'field2'=>'zen'),
	array('field1'=>105, 'field2'=>'bar'),
	array('field1'=>100, 'field2'=>'foo'),
	array('field1'=>200, 'field2'=>'yellow'),
	array('field1'=>200, 'field2'=>'any'),
);
How would you approach if you want to sort the array first by field1 and then by field2. That is sort the array by field1 but for field1 values that are same, sort by field two.. just like the SQL equivalent of ORDER By column1, colum2..

usort($arr, function($a, $b){
	if ($a['field1']>$b['field1']){
		return 1;
	}elseif($a['field1']<$b['field1']){
		return -1;
	}else{
		return strcasecmp($a['field2'], $b['field2']);
	}
});

Symfony file upload SplFileInfo::get error

Working on Symfony form that has a file upload and got the above error when I try to save it.
The form is build from entity which has the following format:

class MemberFile
{
    /**
     * SymfonyComponentHttpFoundationFileUploadedFile object
     */
    protected $file;
    /**
     * @ORMId
     * @ORMColumn(name="file_id", type="integer")
     * @ORMGeneratedValue(strategy="AUTO")
     */
    protected $fileId;
    
    /**
     * @ORMColumn(type="string", length=255)
     */
    protected $path;
   // additional member variables and getters and setters goes here...
   .....
    public function upload()
    {
        if (null === $this->file)
            return;
        $this->getFile()->move(
                $this->getUploadDir(), $this->file->getClientOriginalName()
        );
        $this->setSize($this->file->getSize());
        $this->setFileType($this->file->guessExtension());
        $this->path=$this->file->getClientOriginalName();
        $this->file=null;
    }
}

And the form is constructed inside the controller in such a way

$member_file=new MemberFile();
        $form=$this->createFormBuilder($member_file)
                ->add("file")
                ->add("save", 'submit')
                ->getForm();

Right after the appropriate action is requested, I called $member_file->upload() after validation to get the above error..

How I solved it..
1. I checked if the file has been properly uploaded despite the error
-> yes it was uploaded
2. Checked if the original tmp file is still intact –
-> NO and BINGO!
Since the file has been moved, the subsequent operations on $this->file can not be done appropriately.
Solution
Just move those operations before you call move file..

    public function upload()
    {
        if (null === $this->file)
            return;
        $this->setSize($this->file->getSize());
        $this->setFileType($this->file->guessExtension());
        $this->path=$this->file->getClientOriginalName();
        $this->getFile()->move(
                $this->getUploadDir(), $this->file->getClientOriginalName()
        );
        $this->file=null;
    }

Unserialize giving errors at offset in php

Serialization in PHP is as easy as using serialize function. But to use the serizalized one, we need unserialize(). When you use this if you get an annoying notice of error at offset or something do this

$unserialized_value=@unserialize($serialized_value);
if ($unserialized_value)
{
    //enjoy the unserialized value here.
}

Mind you it won’t be a road blocker after all it is just a notice – but.. just cleaner is better

Country City Longitude Latitude Database setup in php

Ok, a nice Friday night here and I am working on a project that highly involves the geospatial data. For that I needed data comprising the info I needed.
Thankfully this website provided me the data as one big text file.

Then I wrote this simple snippet for porting the data to my kitchen database 😉
The script should be used only for temporary purpose and by no means on production. It doesn’t do any sanitation or what so ever the good programming.. but it does the job!
I created country_city table with the desired columns only;

CREATE TABLE `country_city` (
  `country_city_id` int(11) NOT NULL AUTO_INCREMENT,
  `country_code` char(2) NOT NULL,
  `city_name` varchar(100) DEFAULT NULL,
  `region` varchar(100) DEFAULT NULL,
  `latitude` float DEFAULT NULL,
  `longitude` float DEFAULT NULL,
  PRIMARY KEY (`country_city_id`)
) ENGINE=InnoDB AUTO_INCREMENT=3170001 DEFAULT CHARSET=latin1

Then I run the following code to populate the data.

   <?php
   /**
    * @author Kaleb Woldearegay 
    * Code to be used "as is". Not responsible for any consequences after using the code.
    */
   const ROWS_TO_INSERT = 5000;
   $file_handle="/path/to/worldcitiespop.txt";
   $fh=fopen($file_handle, 'r');
   $query_pool=array();
   $db_handler=mysql_connect("localhost", "root", "");
   mysql_select_db("your database here");
   //assumed the database is connected at this moment..
   while(!feof($fh))
  {
      $line=fgets($fh, 1024);
      $data=explode(',', $line);
      $city=mysql_real_escape_string($data[1]);
      $query_pool[] = "(null, '{$data[0]}', '{$city}', '{$data[3]}', {$data[5]}, {$data[6]})";
      if (count($query_pool)>=ROWS_TO_INSERT)
      {
          $query = "INSERT INTO country_city VALUES " . implode(',', $query_pool);
          if (!mysql_query($query, $db_handler)) die('Error: '. mysql_error($db_handler));
          $query_pool=array();
      }
  }

That is it,
Enjoy!