Posts

Doctrine deserialize entity and merge recursively

When you serialize doctrine entity and later unserialize you all lazy loaded associations are gone. Initializers won't fetch the data from database as well. One approach could be eagerly fetch all the associations you will need after deserialization. But there is another and more easy and memory effective way. You can do merge() on your entity to "restore" it. But you need to merge each entity you plan to use that could be quite annoying and sometimes impossible. So save your efforts and use recursive merging function above: <?php use Doctrine\ORM\EntityManager; class RecursiveMerge { /** * @var EntityManager */ protected $em; public function __construct ( EntityManager $entityManager ) { $this -> em = $entityManager ; } /** * Merge entity recursively * * @param object $entity * @param int $depth recursion depth to avoid cyclic references issue * * @return object ...

Update third-party composer package in your project

Sometimes you encounter some issue or would like to add some feature to the open source package you use in your project. And it useful enough to be contributed to the original package. Or you fixed some bug and want to share it with package maintainer. The best way (and usually the only way) to do this is to fork the package on github and send the pull request. But what if your application can't work without this fix?  The simplest way to resolve this matter is to move package from vendor to your project and maintain it there. But this approach has a few flaws - it is quite hard to keep library up to date with original and not so easy to contribute to the package. It is much better to fork the package, switch composer to your fork, fix the bug and contribute it back on github. So the steps are: Fork the package on github Just go to the package github page and press button "Fork". As a result you will have a copy of the original package in your account, like a...

Doctrine DQL or SQL

Developers that use Doctrine are often puzzled on what should they use for SELECT queries - DQL or SQL? Short answer: both. Long answer: Official Doctrine documentation here says: A common mistake for beginners is to mistake DQL for being just some form of SQL and therefore trying to use table names and column names or join arbitrary tables together in a query. You need to think about DQL as a query language for your object model, not for your relational schema. That page clearly tells us: don't use DQL to built complicated and heavy queries. But what about database independent code? Query building? You might ask... For former question Doctrine has whole  DBAL layer located in  Doctrine\DBAL namespace, for latter it has  Doctrine\DBAL\Query\QueryBuilder which builds pure SQL code in similar way as  Doctrine\ORM\QueryBuilder builds DQL and A LOT! of developers don't even aware of its existence! $qb = $this -> connection ->createQueryBuilder(); $qb...

Memcached thread safe lock

It is a quite common problem when cache is expired and multiple PHP processes are trying to update it. There is even a special term for this - "cache slam". The "cache slam" problem is described very good on php.net " If a highly shared cache entry stored, for example, in Memcache expires, many clients gets a cache miss. Many client requests can no longer be served from the cache but try to run the underlying query on the database server. Until the cache entry is refreshed, more and more clients contact the database server. In the worst case, a total lost of service is the result. " You can't do $memcached->set('lock_xyz') and then in some other place if ($memcached->get('lock_xyz')) like described in a lot of suggestions all over the internet. Imaging that 10 processes in parallel are trying to check whether lock exists and if not - set it. All of them will end up with setting the lock and do the cache refresh process. I...

Debug Doctrine SQL query with parameters

Sometimes you need to profile your queries with EXPLAIN to see what makes it slow. To do this you need a real SQL query, not DQL. Of course you can take it from Symfony Debug page, but it won't contain binded data, only "?" marks and the parameters that Doctrine binds. It is quite boring to insert them manually, you loose your time on this, can make a mistake etc. I wrote a simple logger, that can log query with inserted parameters. Installation: composer require --dev cmyker / doctrine - sql - logger : dev - master Usage: $connection = $this -> getEntityManager ()-> getConnection (); $logger = new \Cmyker\DoctrineSqlLogger\Logger ( $connection ); $connection -> getConfiguration ()-> setSQLLogger ( $logger ); //some query here echo $logger -> lastQuery ; //or see the output

Memory efficient array permutation in PHP 5.5 using generators

Generators support was introduced in PHP 5.5. The yield keyword is a really cool thing that allows to write an elegant and memory efficient code. It was existing in another dynamic languages like python for quite a long time and now it is in PHP as well! To demonstrate generators concept, i wrote a sample function that  yields  all permutations of the given array and avoids of data copying on recursive calls: function permute( $array ) { $length = sizeof( $array ); $inner = function ( $ix = []) use ( $array , $length , & $inner ) { $yield = sizeof( $ix ) == $length - 1 ; for ( $i = 0 ; $i < $length ; $i ++) { if (in_array( $i , $ix )) { continue ; } elseif ( $yield ) { $toYield = []; foreach (array_merge( $ix , [ $i ]) as $index ) { $toYield [] = $array [ $index ]; } yield $toYield ; ...

Hackerrank "Is Fibo" challenge solution in Python 3

N is a fibonacci number if and only 5N^2 + 4 or 5N^2 – 4 is a perfect square number  http://en.wikipedia.org/wiki/Fibonacci_number#Recognizing_Fibonacci_numbers Solution in python 3: import math n = int(input()) for i in range(0,n): number = int(input()) if math.sqrt(5 * number ** 2 + 4).is_integer() or math.sqrt(5 * number ** 2 - 4).is_integer(): print("IsFibo") else: print("IsNotFibo") This solution has a complexity O(1) compared to simple solution by adding all numbers from 0 to N that has a O(n) complexity