Serving ZF apps with the PHP 5.4 built-in Web Server

When teaching PHP to newcomers, I have found that (honestly to my surprise) one of the biggest barriers you have to cross is setting the stack up to serve PHP files properly, especially when it comes to Zend Framework apps and other rewrite rule based MVC applications. Even with strong development background, the idea of setting up Web Server configuration to get things working seems foreign to many.

Even as an experienced developer with good knowledge of the LAMP stack setup, setting up new vhosts and other configuration for each new project is sometimes a pain in the ass.

There are of course good news – starting from PHP 5.4, the Command Line Interface (CLI) version of PHP comes with a build-in Web server that can be used to serve PHP apps in development. This Web server is very easy to use – you just fire it up in the right place and it works, serving your PHP files. While it is by no means a viable production solution (it is a sequential, no-concurrency server meaning it will only serve one request at a time), it is very convenient for development purposes.

While it “just works” for simple “1-to-1 URL <-> File” apps, it can work almost as easily for rewrite based MVC apps, including Zend Framework 1.x and 2.x apps and probably for other frameworks as well.

Continue reading

On PHP Extensions

While teaching PHP I mention the term “extension” quite a lot – but I have realized that this may very well be a confusing term for non-PHPers. While most PHP training courses focus on code, I believe getting to know the PHP engine and environment is almost as important as learning to use the language. Extensions are a big and important part of PHP, but they seem to be a big knowledge gap about them and Googling for articles that explain what extensions are, and how they are used and installed, hardly returns good results. So, as part of my attempt to blog about more basic PHP topics, I’ve decided to try and come up with an overview of PHP extensions.

So what are PHP extensions?

An extension in PHP is in fact a module providing some functionality to the PHP Engine. While the term makes it sound like extensions provide some kind of special functionality, in reality many of the language’s most basic functions and classes are provided in extensions. Many extensions are shipped as part of the default PHP distribution, and some are in fact compiled into PHP in such way that they cannot even be unloaded. Come to think of it, perhaps it is best to think of PHP extensions as “language modules”.

Continue reading

Password hashing revisited

From user comments on my recent password hashing post, I’ve learned about a better solution for password hashing – rather than using hashing algorithms designed to be fast such as SHA-1 and SHA-256, use slower, and more important future-adaptable algorithms such as bcrypt. I have to say this is one of the reasons I love this community – you always learn new things.

I won’t repeat the reasons why methods such as bcrypt are preferred (read the comments on the previous post to learn why). However, I will note that starting from PHP 5.3 bcrypt is in fact built-in to PHP – so if you do not require portability to older versions of PHP, bcrypt-hasing could be done very easily, using the useful but a bit enygmatic crypt function:

Continue reading

Generating ZF Autoloader Classmaps with Phing

One of the things I’ve quickly discovered when working on Shoppimon is that we need a build process for our PHP frontend app. While the PHP files themselves do not require any traditional “build” step such as processing or compilation, there are a lot of other tasks that need to happen when taking a version from the development environment to staging and to production: among other things, our build process picks up and packages only the files needed by the app (leaving out things like documentation, unit tests and local configuration overrides), minifies and pre-compresses CSS and JavaScript files,  and performs other helpful optimizations on the app, making it ready for production.

Since Shoppimon is based on Zend Framework 2.0, it also heavily relies on the ZF2.0 autoloader stack. Class autoloading is convenient, and was shown to greatly improve performance over using require_once calls. However, different autoloading strategies have pros and cons: while PSR-0 based autoloading (the so called Standard Autoloader from ZF1 days) works automatically and doesn’t require updating any mapping code for each new class added or renamed, it has a significant performance impact compared to classmap based autoloading.

Fortunately, using ZF2′s autoloader stack and Phing, we can enjoy both worlds: while in development, standard PSR-0 autoloading is used and the developer can work smoothly without worrying about updating class maps. As we push code towards production, our build system takes care of updating class map files, ensuring super-fast autoloading in production using the ClassMapAutoloader. How is this done? Read on to learn.

Continue reading

Say Hi to Shoppimon – Magento Monitoring for “Normal” People

For a while now I have been telling people I am “working on a small project” – and now is the time to unveil the mystery and introduce Shoppimon – a new start-up which I founded together with a small group of friends, and am currently spending most of my time around.

The idea of Shoppimon is simple – we want to provide Web monitoring and availability analysis which will be useable by, and useful to “normal” people – not only the tech guy, the programmer or the IT specialist, but the site owner, the business owner or even the marketing guy – in other words the real stake holder.

Continue reading

Storing Passwords the Right Way

I consider this post a bit of an experiment in writing about what I consider “beginner” material. Not that it is necessarily simple or easy stuff anyone should know, but simply because this is not a “new discovery” as far as I am concerned. Also, I usually try not to write about security related material, as I do not consider myself a security expert. However, since I’m starting to teach a “PHP 101″ course soon (maybe I’ll post more about it in the next few weeks), and since I was asked a few times about this topic recently, I’ve decided to write up my experience on this topic and test the reactions.

So, the topic in question is “what is the right way to store user passwords in my DB”. To be clear, I am talking specifically about the passwords users will use to log in to your application, not some 3rd party password you need to store for whatever reason. This is something almost any application out there requires – unless you interface with some external authentication mechanism (OAuth, openId, your office LDAP or Kerberos server), there’s a very high chance you’ll need to authenticate users against a self-stored user name and password.

Continue reading

My PHP Streams API article was published by php|architect

php|architect, one of the most prominent professional PHP magazines in the world, has published an article I wrote about PHP’s user-space Streams API in its December 2011 issue:

Go with the Flow: PHP’s Userspace Streams API

Almost every PHP application out there needs to read data from files or write data to files – or things that look like files but are not quite files – these unstructured blobs of data are commonly referred to as “streams”. Stream functions allow a scalable, portable and memory efficient way to handle data, and pretty much any PHP developer out there knows how to read data from or write data to a steam. The best part is that you don’t have to be an extension author in order to provide access to any data source as if it was just a regular file. PHP’s userspace streams API allows you do to exactly that, and this article will show you how.
If you’re a subscriber, feel free to read the article and send me your feedback. If not, go ahead an buy the issue :)

XPath regular expression matching in PHP 5.3

Recently I needed to do some text pattern matching in an XML XPath query, and XPath’s built-in sub-string matching capabilities were not good enough.

While XPath 2.0 defines regular expression matching capabilities, it is still not widely implemented and in most available tools there is no easy way to do complex pattern matching on XML nodes.

Or is there?

In his blog Thomas Weinert recently gave an intro to using DOM and its XPath capabilities in PHP, but one of the cool features of DOM’s XPath, available starting from PHP 5.3.0 (have you upgraded yet?), is that the DOM extension supports registering pretty much any PHP function with the XPath engine, and using it inside XPath queries.

Here is a quick example showing usage of PHP’s own preg_match() in an XPath query, to find all the external links in Wikipedia’s PHP article:

// Supress XML parsing errors (this is needed to parse Wikipedia's XHTML)
libxml_use_internal_errors(true);

// Load the PHP Wikipedia article
$domDoc = new DOMDocument();
$domDoc->load('http://en.wikipedia.org/wiki/PHP');

// Create XPath object and register the XHTML namespace
$xPath = new DOMXPath($domDoc);
$xPath->registerNamespace('html', 'http://www.w3.org/1999/xhtml');

// Register the PHP namespace if you want to call PHP functions
$xPath->registerNamespace('php', 'http://php.net/xpath');

// Register preg_match to be available in XPath queries 
//
// You can also pass an array to register multiple functions, or call 
// registerPhpFunctions() with no parameters to register all PHP functions
$xPath->registerPhpFunctions('preg_match');

// Find all external links in the article  
$regex = '@^http://[^/]+(?<!wikipedia.org)/@';
$links = $xPath->query("//html:a[ php:functionString('preg_match', '$regex', @href) > 0 ]");

// Print out matched entries
echo "Found " . (int) $links->length . " external linksnn";
foreach($links as $linkDom) { /* @var $entry DOMElement */
    $link = simplexml_import_dom($linkDom);
    $desc = (string) $link;
    $href = (string) $link['href'];
    
    echo " - ";
    if ($desc && $desc != $href) {
        echo "$desc: ";
    } 
    echo "$href\n";
}

Note the use of php:functionString() as an XPath function, calling preg_match(). functionString() will pass XML entities such as @href as a string into the function, which is different from calling php:function() which, as far as I have seen, will pass parameters without casting them to a string first (however I am not sure what exactly they are passed as… maybe someone who knows can elaborate?).

Pretty useful huh?

Debugging CLI PHP with Zend Server and PDT on Linux and Mac

I’m working on a small PHP application and a big part of it are some CLI scripts which will be executed in the background. Some of these scripts are quite complex, and I got to a point where I need to use a debugger in order to figure out what’s going on.

I started hacking around with my locally-installed Zend Server CE and Zend Studio. I always knew how to manually start CLI debug sessions with Zend Studio (well, I knew, but forgot ;-) ), but then I figured, why not write a small shell script to automate the process, and learn a little about the Zend Debugger protocol on the way?

Here is what I did:

First, create the following shell script. I placed it at /usr/local/zend/bin/php-dbg (alongside the other Zend Server executables, which if you use Mac OS X will be at /Applications/ZendServer/bin):

#!/bin/sh

# Wrapper script for debugging PHP CLI scripts with Zend Studio
# Tested with Zend Server 4.0.0 Beta and Zend Studio for Eclipse 6.1.1
# Shahar Evron [shahar.e at zend], 2009-02-20

# Defaults
DFLT_PORT="10137"
DFLT_HOST="127.0.0.1"
DFLT_PARAMS="debug_fastfile=1&use_tunneling=0"

# Load Zend Server environment variables
. /etc/zce.rc

# Did the user specify the debug host / port?
if test "x$DEBUG_HOST" != "x"; then
  if test "x$DEBUG_PORT" != "x"; then
    QUERY_STRING="&debug_port=$DEBUG_PORT"
  else
    QUERY_STRING="&debug_port=$DFLT_PORT"
  fi

  QUERY_STRING="$QUERY_STRING&debug_host=$DEBUG_HOST&$DFLT_PARAMS"

# If no host/port were specified, try to auto-detect
else
  QUERY_STRING=`wget http://localhost:20080/ -O - 2> /dev/null`
  if test $? -ne 0; then
    # Fall back to defaults
    echo "Unable to auto-detect Zend Studio settings, using defaults" >&2
    QUERY_STRING="&debug_port=$DFLT_PORT&debug_host=$DFLT_HOST&$DFLT_PARAMS"
  fi
fi

DBG_SESS_ID=`date +%s`
QUERY_STRING="start_debug=1&debug_stop=1$QUERY_STRING&debug_session_id=$DBG_SESS_ID" 

QUERY_STRING=$QUERY_STRING $ZCE_PREFIX/bin/php -c $ZCE_PREFIX/etc/php.ini $@

Going over this code might teach you some surprising things about how Zend Debugger and Zend Studio talk to each other ;) I’m not going to go into the details now, but if you have questions feel free to ask.

Next, make this script executable – just run ‘chmod +x <path-to-script>‘ – and you’re good to go.

Here is how to use it:

  • If you have PDT or Zend Studio running locally (on the same machine as the server), just run:

    # /usr/local/zend/bin/php-dbg <script you want to debug>

    That would just work in most cases – if it works you can stop reading now ;-)
  • If you are running the script on a server, but your PDT / Zend Studio is on a different machine (in the same LAN – no NAT or firewall!) you can simply specify the IP address or host name of the machine that runs PDT / Zend Studio as the DEBUG_HOST environment variable. For example:

    # DEBUG_HOST=10.1.2.3 /usr/local/zend/bin/php-dbg <script you want to debug>
  • If you are running the script on a remote machine (as above) and your Zend Studio listens on a port other than 10137, you can also pass the DEBUG_PORT environment variable to override the default port.
  • Also, don’t forget to make sure that the machine that runs your Zend Studio is in the list of allowed debugging clients. You can check it at the Zend Server GUI on Server Setup -> Debugger.
  • If you are running the script on a remote host and there’s a firewall / NAT between you and the server (e.g. you are in an office LAN, trying to debug a script on a remote production machine which is not in your subnet) you’ll probably need to use SSH remote port forwarding to forward connections to your PDT / Zend Studio. I won’t get into how to do it right here – unless you insist.
  • If you want to only type ‘php-dbg’ when running instead of the full path, you can place the file in your $PATH (e.g. in /usr/local/bin) or even better, Add /usr/local/zend/bin (or /Applications/ZendServer/bin) to your $PATH – you can do that by adding the following line to ~/.bashrc:

    PATH=$PATH:/usr/local/zend/bin

Upon running the script, a debug session should simply pop-up in your PDT / Studio and you’ll be able to debug. How cool is that?

BTW: This has been tested with Zend Server 4.0.0 beta1 and Zend Studio 6.1.1. It should work with other versions of Studio as well. In fact, it can also work without Zend Server as long as you have Zend Debugger installed – but why ruin a perfectly good plug?

If you improve the script or find bugs, let me know! Also, if you know how to get the same thing going with xDebug, let me know and I’ll add it to the script.

Seven Things – Tagged by Ivo Jansch

“I was hopping along, minding my own business, when all of a sudden, up he comes…Cures me! One minute I’m a leper with a trade, next minute my livelihood’s gone!”

So apparently I was tagged by non other than the mighty Ivo Jansch, thus forced into some silly chain-blogging game. After managing to teach everyone in my life including the tech-clueless to never forward any chain mail to me (except for my grandma – I did get her to stop but then she sometimes forgets not to do it), I get bitten by the most tech-savvy people I might know :P

Well, I can’t say no – especially after being titled “Product Manager and Smart Guy at Zend” (for a short period of time that was almost my official title BTW). Of course I’ll play along! It’s also interesting to see how far this goes :)

So here are seven things about me you might or might not know:

  • I never went to university – I’ve noticed some people state what their major was etc. – so, I never went to university. I never got the chance. While everyone else was in university, I was busy doing other things like learning to write PHP :) I always tell myself I’ll go in a year or to – but now that I’ve gotten into a position everyone assume I have at least a BSc, I don’t want to spoil that :) .
  • I never took any official CS training – I’ve frequently found it boring the way it was taught in school. Don’t get me wrong – I love CS and I sometimes find it exciting – but I enjoy it much more when I get to teach myself. I also tend to believe CS is nice but it’s a tool – not really a “wisdom” I’d like to learn in university. I consider other fields like philosophy, history, biology or even mathematics to be far more worth studying. BTW I did take a couple of CS university courses during high-school – I flunked one of them ;)
  • I started programming when I was 7 or 8 – in BASIC. Well, it was nothing impressive but this is how I started. I then went through some Pascal and some C but never got to any level worth talking about. Then in high-school there was the web, and I started playing with it, first with HTML and then with Perl writing CGI stuff. Pretty much at the same time I started experimenting with Linux.
  • I did that while majoring in Cinematography. Yes – the only thing I did learn professionally was making movies, and I still have a lot of passion for it. I especially enjoyed directing, filming and editing. I did try working for some time on several junior technical positions in the local film industry (2nd assistant camera operator etc.) and did get my name in the credits of some movies (who were major in Israel – so there you have it Ivo ;) ) but working for the “industry” so to speak was not so great, and I decided to drop it.
  • Just like most male citizens of Israel I did my military service after highschool – and didn’t get to touch a programmable computer for 3 years (I did get to touch some computers but they were not the kind you want to mess around with). I even almost became an officer (which means I could have spend more than those 3 years in the army) but I didn’t run fast enough. I still spend a few days every year in reserve training, but sometimes they let me off the hook when I have to go to some PHP conference :)
  • When I got out of the army and back into the real world, Perl was gone and all of a sudden there was PHP everywhere. I found out I could write the same app I wrote in Perl in a month in about a week in PHP, and the rest is history. Back at the time I wrote my first PHP app – a web site which is still running today. I looked at the code a few months ago and almost puked.
  • Before working for Zend, I worked for a local ISP which as managed by the biggest Linux geek I’ve met (no wonder it’s out of business by now) – that was a lot of fun. Before that, I did all sorts of things – I herded goats, I picked cherries and I grew long curly hair. I got to Zend by pure chance – I didn’t even knew they were an Israeli company until I met a cousin of mine who told me he was working there!

So… those are my seven things!

And now, who to tag? I have very few candidates left – I hardly have any blogging friends who haven’t already been tagged… So here are my people, hopefully they’ll forgive me:

  • Nir Yariv – friend, family member, and one of the smartest (infrequent) bloggers I know (he’s also the guy who got me into Zend).
  • Christer Edvartsen – fellow PHP coder, ZF contributor, and occasional (one a year or so) drinking buddy
  • John Coggeshall – Ex-Zender, Current CTO at ACS, PHP author, and well, another occasional drinking buddy
  • Stas Malyshev – PHP Internals Guru and Zend’s 1st employee
  • Boaz Rymland- Another ex-colleague, Drupal expert and a certified social worker
  • Andi Gutmans – Fellow Zender and, wel… you all know him don’t you?
  • Zeev Suraski – Well you know him too don’t you?

Well… that’s my list – let’s see how many of them step up to the plate!

Oh – and here are the rules for any bloggers who decide to follow up:

  • Link your original tagger(s), and list these rules on your blog.
  • Share seven facts about yourself in the post – some random, some wierd.
  • Tag seven people at the end of your post by leaving their names and the links to their blogs.
  • Let them know they’ve been tagged by leaving a comment on their blogs and/or Twitter.