PHP 10.0 Blog

What if…

Posts Tagged ‘PHP’

5.4 is out!

Posted by Stas on March 5, 2012

Since May 2011 we have worked on releasing PHP 5.4, and now it happened. Thanks everybody who helped with it!

PHP 5.4 has some new and exciting features – for some of them, like traits, I have no idea right now how they will work out and what people would do with them. It’d be very interesting to see.
For some of them, I feel they are basic common sense and long overdue in PHP (of course, not everybody may share my opinion ;) – like ['short','array','syntax'] or detaching <?= from INI settings. Some were just missing features that we didn’t catch up with before – more fluent syntax, linking objects to closures, etc.
Some things in PHP, as we have come to realize, were clearly mistakes – like register_globals, some were driven by real needs but proved to do more harm than good at the end – like magic quotes and “safe” mode – so we had to lay them to rest.

One of the best things that happened in 5.4 though is not immediately apparent. The engine behind 5.4 is significantly faster and consumes less memory than before. How much faster and how much less? Depends on your application, of course, but from some benchmarks 10-20% speed improvement and 20-30% memory improvement can be expected. Do your own benchmarks and blog about the results! Also would be a good time to ensure your application runs fine on 5.4 – since 5.4 is now the stable version and you have to start using it! :)

Another great things that happened – and is continuing to happen – is that we are finally moving towards more streamlined release process, towards having more regular releases (expect 5.4.1 release cycle to start in late March-early April and 5.4.1 be out in about a month after that) and more organized feature/change proposal process. There’s a wiki where people can post their RFC proposals, we have a voting process and while we may be still working out some fine details of the procedure, I feel we definitely have improved in this regard. It is time to get some organization into the process – we don’t need to create a bureaucracy, but some process is definitely needed and we’re establishing it.

Yet another thing that is happening – PHP project is slowly but surely moving from SVN to Git. This will be a great improvement. Having used Git for the last couple of years, I can clearly see that it can make many things we’re doing in PHP everyday so much easier. Can’t wait for it :) Also makes easy for people to do pull requests and for core devs to merge them, among other things – should make bug resolutions, etc. work faster.

And after catching our breaths a bit and relaxing soon there will be time to think what we do in 5.5 – remember the thing about more regular releases? :) I’ll try to post some thoughts about what I’d want in 5.5 soon.

Posted in Engine, PHP | Tagged: , , | 5 Comments »

Adding new extensions to Zend Studio

Posted by Stas on September 8, 2010

I am using Zend Studio for my everyday PHP work, and I like it. I know many others do too, or use PDT. It has one very cool – though not widely known – feature that allows you you to add unknown extensions to code completion. I.e., if you have some extension, create stub file with PHPDOC descriptions – i.e. something like this:

/**
 * Do stuff
 * @param string $arg
 * @return array
 */
 function dostuff($arg) {}

for each extension function, Studio will know to pick it up. You can put this file into Studio’s prototypes directory – easiest way to find it is just write something like chdir() anywhere, select the name and press F3, the directory of the file that you’ll get is the one you need.

However, the problem is how to create this file. E.g., I’m doing some work with MongoDB lately, and PHP has great Mongo extension – which Studio doesn’t know yet. So how do I create those stubs? Obviously, I am too lazy to manually write them. I went to look for a tool that would allow me to make one – and found none. At least not in 15 minutes I spent looking, so I decided to write my own.

What came out is the Reflector. It uses PHP reflection and PHP’s manual XML sources in order to generate stub file (see example mongo.php on git to check what comes out). Right now it’s not very smart and handles only classes/methods, not functions (probably will fix that soon), but maybe it will be useful to somebody.

Or maybe somebody points me to a tool that does that even better in comments :)

Update: Roy Ganor (who is leading the Zend Studio project) in comments pointed me to the source of the Studio generator script. It will generate stubs for all extensions you have, as I can see. Try it out. Thanks, Roy!

Posted in PHP | Tagged: , , , , | 10 Comments »

zf book review

Posted by Stas on February 4, 2010

As I mentioned before, I got the book Zend Framework 1.8 Web Application Development for review. It took me a bit more time than I though to do this (one of the reasons will become clear soon) but here it finally comes.

I think it is a great book for somebody who is somewhat acquainted with Zend Framework and wants to get really good at working with it. It covers a lot of ground, so if you never worked with ZF before you might be a bit overwhelmed by the amount of stuff going on (then again, maybe I am underestimating you :) ), so you may want either skip some detail to return to it later when the need arises or have a run through a very basic tutorial for getting to know how the framework works before. The book itself has the basic startup section but I feel for a complete newbie it still might be a bit tough to keep up with the amount of the material in the book. That of course will come handy later when you got the basics figured out.

I personally am a big fan of learning by example and I think one line of code is often worth a hundred words, so I was really pleased that this book is based on building a complete application and comes with full application code to accompany it. The application is a storefront with an admin interface, so it covers most of the common tasks in a typical PHP application.
While it means that on the road there were certain decisions to be taken, and certain ways of doing things will be chosen over certain others, the author clearly identifies the decision points and explains the reasons – i.e. why certain things go to a model and not controller, why this extension point and not that one is used, etc. ZF has a very rich set of features, so there’s no single “right way” to do all things – but the book certainly shows you one of the ways to reach the complete and nicely structured application.

I actually took a bit of an experiment – as I was at the time building some ZF-based application, I decided to use the book as a first reference for any question that I needed with the app. I am pleased to report that the book indeed proved very helpful and I was able to find most of the advanced topics – like the use of ACLs, interactions between forms, views and decorators, modifying the behavior of the standard ZF classes, etc. – answered in the book and demonstrated in the code. The author successfully avoided the temptation to quote the manual extensively and instead picks up where the manual leaves off – i.e. how does one use stuff that the manual describes in practice.

The book also covers – albeit somewhat lightly – the topic that is neglected by so many other ZF books – namely testing. It shows how to setup the test environment and how to execute some basic application tests. Ideally, I would like the topic of tests to be much more prominent and featured as something parallel to development and not something you do after (though I know that’s how it rally happens many times ;) ) – but I know there’s only so much you can put into one book :)

Summarily, I think it is a good book to have if you do or about to do serious ZF development.

Posted in PHP, zend framework | Tagged: , , | 4 Comments »

hiphop for php

Posted by Stas on February 3, 2010

By now probably everybody that is connected to PHP world knows about Facebook’s HipHop.
So here are my thoughts about it.

1. This is a very cool and exciting technology. There were multiple attempts to do this in various ways, and from what it looks, HipHop is the most successful and appealing. I know doing these things is not easy – I tried something like that myself somewhere back in 2006 but was unable to go past very basic examples (I also made a mistake of choosing C instead of C++ as target, which I now think was not a smart decision). And the progress and support for almost all of the PHP magic is definitely great. There still are unsupported areas, but mostly are dark corners into which not many people venture (or should venture, at least :)

2. I do not see it as a replacement for php.net code or Zend Engine. The mainstream of PHP development still happens in the community around php.net and I do not think it is going to change anytime soon. I also see the fact that HipHop engine basically re-implements all the extensions as a serious disadvantage, for which the solution should be sought, even though I completely understand the technical reasons for doing so. I do not know which kind of the solution but while for the company like Facebook it might be OK to “freeze” certain set of extensions and features and maybe catch up periodically, I think it is obvious how such model can be a problem for the wider adoption.

3. If we talk about broader adoption of this technology in a wider PHP world, there are some serious challenges to consider:

  • Plugins: right now, you must compile your whole application. However, many real-life applications have extensive plugin models, which consist of their main competitive advantage – take WordPress, Drupal, Magento, any Zend Framework app – all of these allow to write custom plugins and run them alongside the main code base. The model in which you have to rebuild whole application each time you add/change a line of code is not acceptable in these circumstances.
  • Modularity: this is connected to the above, but is a bit different. PHP right now runs on Apache, IIS, Lighty, nginx, and tons of other servers in different environments. For the use of the technology in the wide variety of environments PHP is used in, one must be able to modularize  and separate the application PHP code from the runtime and the environment.
  • Portability: I tried to run a bunch of my scripts through the demo that the HipHop team was very kind to give me – and most of them experiences unsupported functions or some function didn’t work exactly as their PHP counterparts (random example: PHP’s fopen() would error out given empty first argument, while HPHP implementation would open the current directory as file. There are more such things…). Now, I admit, it would be very easy to fix them, to use different functions and they would work, but again I think it’s obvious how it can be a problem for a PHP programmer, if you are not coding targeting HipHop specifically – and especially of you use 3rd-party code. Having different implementations always presents portability challenges.
  • Thread-safety: A huge problem with PHP thread-safety is third-party libraries. Many of them are not thread safe either explicitly, or, even worse, implicitly – i.e. they just have either bugs or information leaks between threads (like changing some setting in one thread and feeling its effect in another – imagine chdir() leaking through the thread boundaries – see how it can be a problem?) HipHop team’s answer to this question was “we had fixed all those extensions” – which, without diminishing the capabilities of this excellent team, I think is not a satisfactory answer. It very well may be that they indeed fixed all the problems they could see in the code they run – but let us not forget they run one (albeit huge) application. I have hard time believing they have fixed every threading problem with every C library in existence that has interface to PHP and will continue to do so as long as C libraries exist. This of course goes back to modularity question, since here we have coupling between compiling and runtime model.
  • Debugging: obviously, debugging C++ code is orders of magnitude harder than PHP code. So you either need ninja debugging skills, or a very good set of tools to allow you to identify a problem in a live server running non-source PHP.

4. I also see certain danger potential in the success of this project. The danger primary being that the performance is very important in the web world, and it can give an incentive to the PHP community to change PHP in ways that may be better for performance, but would make PHP into being an entirely different language. The obvious example of this is strict typing – strict typing, of course, would help the compiler a lot in figuring out what’s going on with the code. However, I am not convinced at all that it would make the life of a PHP programmer easier. I know there are a number of proponents of this but I am still not convinced it’s the way for PHP to go. And there might be other incentives like this – i.e. to add or drop features to PHP, or avoid using certain constructs and features, for the sole reason of making it more compile-able. Now, there’s nothing wrong with being compiler-friendly, but I don’t think for a language like PHP it should be the primary motivation.

Re-reading these notes I realized some of it might give an impression that I dislike the technology. It is absolutely not so – on the contrary, I think it is a great addition to the PHP world and I want again to congratulate the HipHop team on a huge achievement and thank them for making the PHP world better and more exciting. It would be very interesting to see how this develops and how and if the problems can be overcome and how this technology changes the PHP world and is changed by it.

Posted in Engine, PHP | Tagged: , , , , , | 8 Comments »

Ruby-like iterators in PHP

Posted by Stas on January 27, 2010

I’ve started playing with Ruby recently, and one of the things that got my attention in Ruby were iterators. They are different inside from regular loops but work in a similar way, and looks like people (at least ones that write tutorials and code examples ;) ) like to use them. For example, you can have:

arr = {"one" => 1, "two" => 2, "three" => 3}
arr.each do |key, val|
print "#{key}: is #{val}\n"
end

which iterates over a Ruby hash and prints:

three: is 3
two: is 2
one: is 1

So it got me thinking – suppose I wanted to do something like this in PHP (suppose I don’t like regular loop-y iterators for some weird reason). Naturally, I wouldn’t get it in the same concise form as Ruby does, since I can’t change the syntax. But I could get the essence. Let’s try it. First, the main iterator:

class RubyIterator {
  protected $_body;

  public function __construct($body) {
    if(!is_callable($body)) {
      throw new Exception("Iterator body should be a callable");
    }
    $this->_body = $body;
  }
  public function yield()
  {
    $args = func_get_args();
    call_user_func_array($this->_body, $args);
  }
}

Next, less try to make some class that uses it:

class RubyArray {
    protected $_arr;
    public function __construct(array $a)
    {
        $this->_arr $a;
    }

    public function each($body) {
        $iter = new RubyIterator($body);
        foreach($this->_arr as $k => $v) {
            $iter->yield($k$v);
        }
    }
}

and then:

/*
arr = {"one" => 1, "two" => 2, "three" => 3}
arr.each do |key, val|
    print "#{key}: is #{val}\n"
end
*/
    
$arr = new RubyArray(array("one" => 1"two" => 2"three" => 3));
$arr->each(function($key$val) { echo "$key: is $val\n"; });

and the result the same, of course. Or, let’s try with ranges:

class RubyRange {
    protected $_from$_to;
    public function __construct($from$to) {
        $this->_from $from;
        $this->_to $to;
    }
    public function each($body) {
        $iter = new RubyIterator($body);
        for($i=$this->_from$i<=$this->_to$i++) {
            $iter->yield($i);
        }
    }
    
}

and use it:

/*
r = 1..10;
r.each do |i|
    print "#{i*i}\n"
end
*/

$rr = new RubyRange(110);
$rr->each(function($i) { echo $i*$i."\n"; });

which indeed produces:

1
4
9
16
25
36
49
64
81
100

And so on – if one wanted, whole set of iterator methods could be implemented (I’m of course too lazy to do that :) ). I wonder if there are use cases that we can’t do there.

Posted in Functions, PHP | Tagged: , , , , , , | 26 Comments »

5.2->5.3 migration script

Posted by Stas on January 25, 2010

Wrote an article on DevZone about migration script from php 5.2 to 5.3. This little script can save some time when you consider to move your codebase to run under 5.3 (which you should :) ).

This script doesn’t do everything I’d like it to do – specifically, I’d like to make it try to figure out all kinds of messy reference scenarios, but I’m not sure how yet. And if you have other idea, please comment there or here. It’s on public git, so you can take it and modify if you wish.

Posted in Engine, PHP | Tagged: , , | 3 Comments »

new zf book

Posted by Stas on November 18, 2009

Received a new book – Zend Framework 1.8 Web Application Development – for review. I just browsed through the pages, and it looks nice. Will take some time over the weekend to read it through.

Posted in PHP, zend framework | Tagged: , , | 5 Comments »

Zend Server PHP sources

Posted by Stas on October 23, 2009

I was asked about PHP going with Zend Server, specifically from which sources it is built – as we don’t ship source packages for the builds. Since Zend Server includes PHP build that can have some patches applied from SVN past the release (i.e. if the package has version 5.2.10 it might have some patches that were in SVN 5.2 branch past 5.2.10 tag) – I think it is important that people know what they are going to run if the use Zend Server.

So, there is some solution for that – we do have packages with PHP sources called php-5.2-source-zend-server and php-5.3-source-zend-server. If you are using RPM/DEB setup for Zend Server, you can just install these packages by name and get it in /usr/local/zend/share/php-source/ and if you install it any other way (or just curious?)  I guess you could take packages directly from RPM or DEB repo and install them manually :)  Those are exactly the sources from which the binaries are built.

What we don’t have yet is a changelog that describes in detail which patches are going into that release additionally to pure X.Y.Z tag. I’ve asked Powers That Be to add it, so hopefully it’d happen soon too.

P.S. If you need help on how to add custom extension to ZS, we have DevZone article about it.

Posted in PHP, Zend Server | Tagged: , , , , | 2 Comments »

syntax I miss in PHP

Posted by Stas on August 21, 2009

Here are some syntax additions I’d like to see in PHP:

1. a()()
When a() returns a callable object (such as a closure) the second set of brackets would call it. That would allow to write some neat code. I am working on a patch for that but it’s a bit harder than I thought.

2. a()[$x]
This is kind of obvious, I wonder why don’t we have it? Should also be able to be an lvalue, though unless a() returns by-ref or return value is an object it may not do what one wanted.

3. foo(1,2,,4)
Syntax to skip a parameter in a call, which then will be substituted with the default as defined by the function. Would come handy if you have function with many defaults, and you only want to change the last one but leave the rest alone – now you don’t have to look up the actual default’s values.

4. foo(“a” => 1, “c” => 2, “d” => 4)
Named parameters call, which allows you to specify parameters in arbitrary order by name. Would allow to build nice APIs which could accept wider ranges of parameters without resorting to using arrays. That’d also imply call_user_func_array() would accept named arguments.
The problem here might be what to do with unknown arguments – i.e. ones that the function did not expect. I guess the function could just ignore them.

5. $a = ["a", "b" => "c"];
I’d really like to have short array syntax. Yes, I know it was rejected so many times already, but I still like it.

Posted in Engine, PHP | Tagged: , , | 64 Comments »

More on PHP performance

Posted by Stas on July 13, 2009

After writing the post criticizing Google’s “performance advice” for PHP beginners, I started thinking – OK, I don’t like Google’s advice, what would I propose instead?

So here are my thoughts about what would be good for the beginner to consider when he starts with PHP performance optimizations. Note that I do not say it’s the only thing you should do – there are a bunch of articles, talks, blogs, etc. about PHP performance and many of them contain very good advice and go into much more details than I intend to go into. But I think the items below are ones that you should ensure you are doing to the full extent before you go to look around for performance tricks.

Also, from the start I want to say that I work for Zend Technologies and I participated in development of many Zend solutions, both free and commercial. I am going to mention both kinds in this article, where relevant. I am aware that there are alternative solutions, but I will mention the ones I know the best. So please do not take this as commercial advertisement or any claim on relative merits of other solutions – it is not the intent. The intent is to give general direction and some examples, if somebody prefers other solutions in the same direction – that’s fine.

Bytecode cache
If you care about performance and don’t use bytecode cache then you don’t really care about performance. Please get one and start using it. If you want ready-made commercially-supported solution with nice GUI, etc., look at Zend Server, if you’re more into compile-it-yourself command-line then you may want to look at APC, or other alternatives.

Profiling
Profile you code before you start optimizing it! Otherwise it would be like travelling around a foreign city with signs written in an unreadable language witout any map or GPS. You’ll probably get somewhere, but you wouldn’t have any idea where you are, where you should go and how far are you from the place you need to be. Profiling would allow you to know which parts of code are worth investing into and which aren’t. You can use Zend Studio/Debugger or Xdebug for that.

Caching
Most PHP installations run in “shared nothing” mode where as soon as the request processing ends, all the data associated with the request is gone. It has some advantages, but also one big disadvantage – you can not preserve results of repeated operations. That is, unless you use caching.
You should look into caching all operations which take considerable time and can return the same result for a prolonged period of time or same data set. That may include configurations, database queries, service requests, complex calculations, full pages or page fragments, etc., etc. Caching expensive operations is one of the most powerful performance improvements you can do.
There are numerous low-level caching solutions – memcached, APC, Zend Server (you can find a good guide to it on DevZone) and others. On top of it, you may look into Zend Framework’s caching infrastructure – which support the backends described above and more and makes caching much easier.

Optimize your data
Usually the most expensive places of the PHP application are where it accesses external data – namely, database or filesystem or network. Look hard into optimizing that – reduce number of queries, improve database structure, reduce filesystem accesses, try to bundle data to make one service call instead of several, etc. For more advanced in-depth look, use tools like strace (Unix) and Process Explorer (Windows) to look into system calls your script produces and think about ways to eliminate some of  them. You would not be able to eliminate all of them but each of them is a worthy target.

Don’t try to outsmart the engine
There are a lot of “tips” floating around about which constructs in PHP are faster or slower than others. I think you can safely ignore all of these tips, especially if you’re a beginner. Odd are, 9 cases out of 10 they won’t give you any improvement at all, and in the remaining one case it will be either not applicable in your code or not worth the time spent on it. Yes, there are ways to save couple of opcodes and remove couple of lookups here and there – but unless you’ve already done with all of the previous steps it is not worth it. And some of the advice out there will actually make you code slower, less robust and less secure without you even noticing. So I think for the beginners is better to stay away from trying to outsmart the engine altogether.

Benchmark in real life

Many of the advices I mentioned above have benchmarks as a proof. The problem is these benchmarks always test only a short piece of code. However, you would not be running that one-liner – you would be running the whole big application. This reminds me of a joke about a physicist that developed the model of a spherical horse in vacuum in order to use it to win bets on horse racing. If you want better chances to win than that physicist, test in real environment, not in vacuum. If you have an idea for some improvement, verify that this improvement actually improves your application, not just an artificial benchmark. If this is impossible, use profile results to estimate potential benefit – if you find a way to optimize function that summarily runs for 0.1% of overall execution time, you probably won’t do any good to the application as a whole.

Leverage the extensions
That seems too obvious, but I have seen a lot of code that duplicates functions available in some PHP extension. There are a lot of functions in PHP and if you do something that others may have done before, check in the manual. You have DOM/SimpleXML extensions for XML, JSON extension for JSON, SOAP extension for doing SOAP, etc., etc. Do not create custom serialization/deserialization if serialize()/deserialize() would work for you.
If you have some very performance-sensitive bit of script and you can do C programming (beginner in PHP doesn’t mean beginner in everything :), consider even making your own extension, it’s not that hard.

Avoid extra notices/errors/etc.
Even suppressed errors have cost in PHP, so try and write your code so it would not produce notices, strict notices, warnings, etc. You may want to enable logging of all errors to examine that. Never enable displaying errors in production though – it will only lead to a major public embarrassment.

Use php.ini-production as a start
If you need a set of php.ini settings which would not hurt your performance and not break anything, look into php.ini-production in PHP source. You may need to change a couple of details (e.g. include path) but it’s a good starting point.

Use big realpath cache
Realpath cache is very useful for the engine when it tries to find the unique full name of the file from just filename or relative path. By default, it’s 16K but if you have a lot of files with long pathes, it’s better to increase the size – it would save the expensive disk accesses.

There are probably more things that could be said, but this post is pretty long already, so I will end it here and you are welcome to add your opinion in comments.

Posted in PHP | Tagged: , , , , | 63 Comments »

 
Follow

Get every new post delivered to your Inbox.