-
PHP 5.4 was released!
Even though is already yesterday news… literally, yesterday 1 March was released.
The complete list of changes is available on php.net.
I’m sorry that we still don’t have scalar type hinting in this version. The only change to type hinting was the “callable” word was added, about which I’ve talked in the closure in PHP 5.4 blog.
Another interesting thing is that this time register_globals and magic_quotes_gpc were really removed, so the old PHP 4 apps don’t get to be compatible anymore with the help of a couple of flags in php.ini.
Also the hex2bin() function was added, of course is not that important, but is interesting that the bin2hex() function existed since PHP 4. 🙂
-
There are moments when you need to see the stack trace, to know how a certain point was reached. There are two native functions for that in PHP: debug_backtrace() si debug_print_backtrace. The first one returns an array and the second will print the stack trace to the screen.
The problem is that this functions must be customized for Magento, because it is very possible that when you’re running debug_backtrace() you can run out of memory before you can send the output to a log file.
Magento has a native function for that purpose: Varien_Debug::backtrace([bool $return = false], [bool $html = true], [bool $withArgs = true]). In order to send the resulting stacktrace to a log file you simply all it with:
1Mage::log(Varien_Debug::backtrace(true, false));
This technique is very useful when you need to see where an certain object is initialized, and what methods were executed up to that point.
-
The concept of closure was introduced in PHP 5.3, with the new “more traditional” syntax for anonymous functions.
PHP 5.3
In PHP 5.3, a closure will rely on the term “use”, which was passing the variables to the anonymous function, making it a closure.
The problem is that the anonymous function will only be able to access the variables that have been passed with “use”. When it comes to objects, there are passed by reference by default, but scalar variables (int, string, etc.) are passed by value, as this is the default behavior in PHP 5+:
1$scalar = 5; 2 3$closure = function () use ($scalar) { 4 return 'Scalar: ' . $scalar . PHP_EOL; 5}; 6 7echo $closure(); // Scalar: 5 8 9$scalar = 7; 10 11echo $closure(); // Scalar: 5
Another problem is that you cannot pass $this when the anonymous function is declared inside an object, so only the public method and properties can be accessed inside the closure.
PHP 5.4
In PHP 5.4 the keyword “use” is optional, and the entire environment where the function was created is available inside the function.
The advantage is that when the anonymous function is created inside another function or method, the anonymous function has access to the environment where it was created, even after the execution of the environment is over. The objects from this environment will be unset, only after the last reference to the closure will be unset:
1class testClass { 2 3 private $changeableVar = 1; 4 private $bigVar; 5 6 public function __construct() { 7 // Allocate a big variable so we can see the changes in memory 8 $this->bigVar = str_repeat("BigWord", 5000); 9 } 10 11 /** 12 * A method that returns the closure 13 */ 14 public function closure() { 15 16 return function () { 17 // Display the value of a private property of the object 18 echo 'Private property: ' . $this->changeableVar.PHP_EOL; 19 20 // Change the value of a private property of the object 21 $this->changeableVar = 2; 22 }; 23 } 24 25 /** 26 * Method that displays a private property 27 */ 28 public function showChangeableVar() { 29 echo 'Private property in method: ' . $this->changeableVar.PHP_EOL; 30 } 31 32} 33 34// Memory befor the objects is created 35echo "Memory: " . memory_get_usage() . PHP_EOL; // Memory: 229896 36 37// Create object 38$testObj = new testClass(); 39 40// Create closure 41$closure = $testObj->closure(); 42 43// Execute closure 44$closure(); // Private property: 1 45 46// Displaying the current value of the private property 47$testObj->showChangeableVar(); // Private property in method: 2 48 49// Memory befor object will be unset 50echo "Memory: ". memory_get_usage() . PHP_EOL; // Memory: 266240 51 52// Unset the object 53unset($testObj); 54 55// Memory after the object was distroyed, there is no big difference in memory 56echo "Memory: ". memory_get_usage() . PHP_EOL; // Memory: 266152 57 58// Run closure after the object in which it was created was unset 59echo $closure(); // Private property: 2 60 61// Unset closure and with it the object environment 62unset($closure); 63 64// Memotry after the las reference to the object (closure) is unset 65echo "Memory: " . memory_get_usage() . PHP_EOL; // Memory: 230416
Callable type hinting
Another new feature introduced in PHP 5.4 regarding closures is the new “type hint”: “callable”. Actually callable is referring to any anonymous function, and even to a new way of calling a method of an object:
1<?php 2 3// A function that uses type hinting 4function typeHinting(callable $a) { 5 echo $a() . PHP_EOL; 6} 7 8// A closure 9$closure = function () { 10 return __FUNCTION__; 11}; 12 13// Call the type hinting function with the closure 14typeHinting($closure); // {closure} 15 16class testClass { 17 public function testMethod() { 18 return __METHOD__; 19 } 20} 21 22// A mock object 23$testObj = new testClass(); 24 25// The new way of calling object methods 26$objCallable = array($testObj, 'testMethod'); 27 28// Call type hinting function with the new method calling way 29typeHinting($objCallable); // testClass::testMethod
I believe that only now we can really say that PHP supports closures, the right way!
-
In one of my adventures in the Magento code. I’ve encountered the following problem: I had to add a link to the breadcrumb.
As the documentation is not so great, after a little debugging (not a lot), I’ve got in to the core Mage_Page_Block_Html_Breadcrumbs.
The method is quite self-explanatory: addCrumb($crumbName, $crumbInfo, $after = false). Since I was there, I took a look inside:
1function addCrumb($crumbName, $crumbInfo, $after = false) 2{ 3 $this->_prepareArray($crumbInfo, array('label', 'title', 'link', 'first', 'last', 'readonly')); 4 if ((!isset($this->_crumbs[$crumbName])) || (!$this->_crumbs[$crumbName]['readonly'])) { 5 $this->_crumbs[$crumbName] = $crumbInfo; 6 } 7 return $this; 8}
What’s interesting is the $after parameter, as you can see, even though it has a default value, is not used anywhere. The rest work’s as expected, probably this is why people don’t complain so much about it.
-
It became a tradition for me to begin my annual review on this subject.
PHP 6 is as close to be released as it was last year, or two years ago, which is without perspective. This year PHP 5.4 reached RC4 and a final version will probably be released soon, this means that work on PHP 6 will not be resumed soon. But more about PHP 5.4 with another occasion, is on my “TODO” list to see what got into RC4.
As the main keyword for me in PHP 5.3 were namespaces, Anonymous functions, closures and garbage collector, in PHP 5.4 it seems that those keywords are going to be traits, the new closures and scalar type hinting, next to many other new features.
When I’ve wrote my first annual review blog about PHP 6, I was mainly working on Romanian websites, hence my desire for a version that will natively support this language and any other without any changes. Back then I was mainly working directly with the language, without using a framework most of the time. But since then a lot of time has passed and many things have changed, now I’m using almost exclusively frameworks and other platforms that are taking me further away from the language, offering me a different architectural perspective.
After more then an year with NCH, I’ve decided that is time for a change. This is also a company from the states with a branch in Romania, and this time is Optaros. Although I wasn’t trying to change my work place, I’ve responded to an invitation to an interview, and long story short, I left. For a long time I’ve wanted to work again for external clients, after working at NCH where all the projects were internal, I’ve wanted a change.
Again the projects are even bigger, with other scalability issues. But I think that makes web development so interesting, the bigger the scalability issues, the bigger the project.
Last year the main keywords were Linux si Symfony framework. For this year that is just ending the main keywords probably were: Magento and Drupal.
After a short period of working with Magento, I can say that it seems incredible how a platform so big has so little documentation and a lot of the time so inconsistent. It is a very complex platform and a lot of things can be done with it, but when it comes to documentation, it seems like the usual approach is to just analyze the core. Coming from the Symfony world, where there are literary books for documentation, available for free, it seems incredible how little and disorganized is the Magento documentation. But this is also a subject for another blog. A think that the Optaros team played an important role in helping me understand how to approach the issues.
Another major event for me this year was the Yahoo! Open Hack Day, event that this year was also held in Romania. I don’t think I’ve ever seen so much enthusiasm and energy in a single place, in a single day. For me as a developer it was an unforgettable experience, one of those moments that remind me why I’ve chosen this profession.
Also this year I’ve passed my PHP 5.3 certification exam, at the beginning of the year. The exam wasn’t as difficult as I’ve expected, even though the tension remains the same. The fact that it wasn’t my first certification exam helped, it’s incredible how much you remember when you start the reading the documentation again. Last year I’ve decided that I have to take at least an certification exam every year, so I have to get started on preparing for the next one.
As a conclusion, 2011 was a good year, full of challenges and accomplishments, even though I haven’t checked a lot of entries on my last year’s resolution, I’ve done quite a few that were not on that list. But now is time for another new year’s resolution.
And now I wish you an 2012 full of achievements! Happy new year!