Posts

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

Do not use service manager's get() function everywhere in Zend Framework 2

If some model or service is required only in the current scope, avoid usage of $sm->get() because your service will never be destroyed . Check reference count of the object that is created with $sm->get(): class CronController extends AbstractConsoleController { public function updateDomainsAction() { $updater = $this->getServiceLocator()->get('Backend\Model\UrlsCoverageUpdater'); debug_zval_dump($updater); die; } } Refcount is 3: object(Backend\Model\UrlsCoverageUpdater)#643 (4) refcount(3){ ... ["doctrine":protected]=> object(Doctrine\ORM\EntityManager)#502 (10) refcount(2){ ... The reason of this behavior is that service manager saves service instance (similar to registry pattern). Any service requested via get() won't be destroyed until request end. Memory usage will constantly grow. Compare to direct instantiation: class CronController extends AbstractConsoleController { p...

PHP extension development with Linux and Eclipse CDT. Developing basic extension with ext_skel

Image
Before you start you should setup your developing environment. How to setup it is explained in one of my previous posts - http://cmyker.blogspot.com/2011/11/php-extension-development-with-linux.html My platform is Opensuse 12.2, PHP 5.3.22, Eclipse CDT 8.0.2. If you are experienced in other Linux environments you're welcome to add HOWTOs to the comments. To make extension development process easier to start PHP source code distribution has a nice ext_skel shell script. This script will build your extension skeleton, actually fully functional extension. It is located in /usr/src/packages/BUILD/php-5.X.X/ext directory. To build your new "helloworld" extension skeleton run: # cd /usr/src/packages/BUILD/php-5.3.22 #  ./ext_skel --extname=helloworld Creating directory helloworld Creating basic files: config.m4 config.w32 .svnignore helloworld.c php_helloworld.h CREDITS EXPERIMENTAL tests/001.phpt helloworld.php [done]. To use your new extension, you will have to exe...

Jqgrid show totals in the footer plugin

This plug-in automatically calculates sum of the all numeric rows in your grid and displays it in the new "Totals" row at the bottom of the grid. jqgrid 4.3.2+ is required. (function($) { $.jgrid.extend({ showTotals: function(options) { var o = $.extend({ total: "Totals", totalRow: undefined, includeRows: [] }, options || {}) return this.each(function() { if (!this.grid) { return; } var self = this; var showTotals = function() { var totals = {}; $.each(self.p.colModel, function(index, data) { if (o.totalRow && o.totalRow == data.index) { totals[data.index] = o.total; } else { var sum = NaN; if (...