Accessing backend system…

We're sorry, but your session has expired due to inactivity. Please use your browser to refresh this page and log in to our system again.

Message goes here.

Message goes here.

Message goes here.

LOGIN / REGISTER
VIEW BASKET
SEARCH:
 
php|architect logo
 
SERVICES
  • MAGAZINE
  • PHP|TEK 2012
  • CODEWORKS 2011/12 TOUR
  • BOOKS
  • TRAINING
  • ADVERTISE
 
CHANNELS
  • NEWS
  • PODCAST
  • DEVELOPMENT
  • OPINION
  • WRITE

Zend Db 2.0 Kicks Off

Posted by Bill Karwin on June 25, 2010
IN Opinion
Tags: database · zend framework
 

Related Posts:

  • Full-text Search with SQLite
  • The NoSQL Hype Curve is Bending
  • MySQL, PostgreSQL Release Milestones
  • Zend Framework 2.0 inches closer to completion
  • ORM Designer

Red Onions by Darwin Bell (Creative Commons Attribution 2.0 Generic)
Ralph Schindler has started the ball rolling on requirements for Zend Db for Zend Framework 2.0.  He announced on the ZF Contributors mailing list:

 

Requirements have been solicited from both community members in various conversations, as well as looking through the issue tracker for feature requests that have been on the backlog due to potential BC breakage. This document reflects those ideas, and it’s now in a position where we’d like to start a discussion on the direction outlined inside it.

I worked on Zend_Db during the push to Zend Framework 1.0, so I was interested to see what the goals are for the next major revision.

Create Zend\DB\Registry

This is promising.  Lots of apps need to use multiple database servers transparently.  Zend Db should support a Composite that maps queries to multiple Db objects, delegating using policies defined by the developer.

Pluggable architecture

This is tricky.  The risk is the one will run afoul of the YAGNI principle, creating plugin hooks that virtually no one needs.  It’s a good time for the developer community to step up and document compelling use cases.  Everyone should instantly recognize how important and useful it would be to have a plugin hook RIGHT THERE.

Distinct abstractions

I.e., decouple the connection adapter from query abstraction features.  Decoupling is often good, but too much of a good thing can make a system harder to use.  Why exactly would one need to do this?  Do we need to mix and match an Oracle connection with a MySQL query abstraction class?

This gets to a more general guideline about writing software requirements documents:  the justification for a feature is not the absence of that feature. The requirements need to be more clear about the problem to be solved, instead of any particular solution.

Addition of DDL query abstraction

This is very hard.  First, DDL varies between vendors even more than DML varies. I put a lot of work into supporting pseudokeys in a vendor-neutral way.  Don’t get me started on data types; there’s almost no single data type that’s supported by every RDBMS vendor, not even INTEGER.

Second, vendor-proprietary DDL features are important.  Think of special index types, table partitioning, storage engine options, or fulltext search functions.  There is very little commonality between vendors in these features,  but when you need them, you really need them.

Third, do DDL operations really need to be run from PHP applications (besides phpMyAdmin)?

Addition of a Metadata sub-component

This is a good idea.  Not that it’s 2010, we should be able to rely more on standard system tables to tell us more about the schema.  Also you shouldn’t have to wire related objects together by assigning their pseudokeys yourself, you should just add one object as a dependent of another, and the objects would consult their metadata to know how they’re related.

However, I recommend strongly:  eliminate cascading update/delete in PHP code.  I regret implementing this.  The RDBMS engine is the only place cascading logic can be implemented while preserving data integrity.

Separate Table & Row Gateway into sub-components of their own

This is another solution in search of a justification.  Anyone who uses an ORM for long realizes that it’s a leaky abstraction; you need to write hand-crafted SQL more often than advocates of ORM frameworks will admit.  The Table gateway is for operations on one table.  Many ordinary queries operate on multiple tables.  Making the Table class be the sole provider of insert(), update(), and delete() operations creates an awkward coupling between those operations and a single table.

Better testability in the Unit Tests

Yes indeed.  Testing has come a long way in the past three-plus years.  It’s true that much of the unit testing of Zend Db classes should be done in isolation (as unit testing should be), using test doubles such as mocks and stubs.

Test setup is another justification for DDL abstraction in Zend Db, but this would be a lot of work for very little gain.  It would be far easier to load vendor-specific SQL scripts through the vendor’s client.

I wrote the infamous Zend Db unit testing framework out of desperation to have some way to run the same set of  tests against all supported vendors of RDBMS.  You need to run tests against live databases. I can’t emphasize this enough.  I found and fixed dozens of bugs during development of Zend Db, that were bugs only for one database vendor.

Base Plugins / Type Converter

The problem with type converters that map SQL data types to native PHP types is that some types supported by SQL that can’t map to native PHP types.  The best examples are 64-bit integers or unsigned integers.  Some SQL data types can only map to PHP strings.

What’s missing?

What about some of the long-running feature requests for Zend Db, like stored procedures, character sets, and support for queries that can’t run as prepared statements?  What about clarifying the difference between a Model and a data layer?

I saw in this first pass at Zend Db 2.0 requirements a lot of implementation plans but not so much requirements as I would define them.  I blogged about this when Matthew Weier O’Phinney wrote a higher-level set of goals for Zend Framework 2.0 some months ago.

Basically, the architecture changes are interesting only to a rarefied audience.  But you can’t pitch a product based on how it’s architected or implemented. You pitch a product based on what users can do with it, and what problems it solves.  What problems do users of Zend Db have, and how will they use Zend Db 2.0 to solve those problems?


About the author—
 
 
 

Simplicity made complicated: character encoding

Posted by Jordi Roura on June 24, 2010
IN Development
Tags: encoding · unicode · utf-8
 

The dangers that lurk behind character encodingBack in the twentieth century, when I was young and tender in university, I had my first experience with the Internet, and the first thing that struck me as odd was that if I wrote an email to any of my colleagues it would arrive garbled and barely readable.  A quick conversation with the sysadmin revealed that “Our mail servers use 7-bit encoding, and we need 8-bit encoding for accents”.  The first thing I thought was “The Americans who wrote the software didn’t know that people were going to use accents?  Big thing not to know…”.  The second thing I thought was “The sysadmins of a university based in Barcelona didn’t realize users were going to write using latin characters?  What were they thinking?”.  And the fact is that as developers we tend to confuse standard with usual, a mistake we all make far too often and although we encounter it almost day-in day-out we (at least I) still haven’t found a way to solve it.

Unicode! scream a few. UTF-8! scream quite a few others.  Yeah right, and all software written in a planned manner, with proper documentation and unit testing is bug free.  There is always a midget or a leprechaun lurking in the shadows, waiting to jump on the data and switch those bits around.  Maybe it’s the form data validation, maybe the request encoding, it could be the database is using a different encoding or, more fun still, a different collation.  And maybe the way the data gets recovered is the culprit.  And let’s not talk about data getting passed around using instant messengers or emails then getting copied and pasted in and out of documents. Finally, when everything has been taken into account and you make sure everything is going in and out in the appropriate manner… Bang!  Now you have a new employee who is Russian, or Chinese, or you have to store data written in the Arabic alphabet.  Dammit, when I was working at a big venue concert an artist insisted his name be printed and announced in binary!

So, enough ranting for now.  Where does the solution lie?  Because there is a solution isn’t there?  Well… yes… sort of.  There isn’t a magic recipe (that I know of) but some best-practices help.  Working only in UTF-8 is advisable while we wait (still, and patiently) for PHP to fulfill its promises of native Unicode support.  Using binary-safe and multibyte functions also helps… but don’t put all your weight on those.  Experience tells that when you have a rebellious string its going to need a lot of massaging.  As with coding in teams, following conventions when manipulating data are very very necessary, and probably your best ally, even if it seems you aren’t going to need them.  Sooner or later a character that your storage system doesn’t support is going to slap you in the face (yes, it will, don’t look at me like that) and being ready will only guarantee that it’s going to be less of a surprise.  Just because something is standard it doesn’t mean it’s going to be bullet-proof.

So remember, be it an address, somebody’s name, product model or whatever, something is bound to break your rules, and you’d better be ready to change them and adapt.  Communication is vital in today’s e-commerce world and bad encoding is emotionally a very bad message.


About the author—
 
 
 

Open source life style

Posted by Marco Tabini on June 23, 2010
IN News ·Opinion
Tags: community · Conference · open source
 

Related Posts:

  • Check it out, tek 11 schedule is up!
  • PHP tours Europe in fall
  • phpDay 2010
  • New PHPWomen initiative
  • php|tek’s Call for Papers is Closing Soon

Open source is a life style. — Michelangelo Van Dam

Some developers identify open source with weekends spent coding and programs given away for free, but this is not the full picture nor a balanced one. Open source consists not only in contributing to projects with code or documentations, but also in every other activity that provides value to the community: you don’t need to patch the PHP core to be active in the open source movement.

For example, in the last year I published a lot of material on my personal blog, including a free ebook on practical testing in PHP applications. As a result of the exposure my articles gave me, I got to be employed as a freelance blogger here at php|architect and to speak at my first conference.

There are also more immediate benefits from writing for the community: if English is not your native language, using it nearly everyday will also improve your proficiency. English is one of the standards of the open source world and of the business one.

Code

Of course also code can be important: for example, my contributions to Doctrine 1 and 2 gave me credibility when writing about it. We usually can’t show our private projects since they are confidential, and certainly a customer won’t let you open source his website.

Writing code samples is a mandatory step in the interviews of every place where you would want to work. If your code is out in the wild, it has double value: first, for the users of the project you helped and second, for you to show your skills to potential employers. If you take the step of jumping from the perspective of an end-user of a framework or a library to a contributor or active developer, would you then need a certification? What sounds better on your résumé, that you can work with Zend Framework, or that you created a part of it?

Moreover, writing open source code makes you learn new patterns and practices, and you can choose what you are interested in so that your work won’t be boring. This is one of the factors that makes working on open source attractive where no monetary reward is present: the joy of hacking.

Once you have started coding on open source projects, your contributions can make your name recognized: people dig into source code very often and @author annotation remains naturally impressed after seeing many of them. Years ago I wondered who this Sebastian Bergmann was.

Open source your career

Thus, participating in the community with code, articles, documentation, and whatever provides value to others can really help your career. Often in subtle ways: the web is open to anyone and you never know who is receiving your content. For instance, Lorna Jane Mitchell came to know that one of the reasons she stands out during candidate selection and now works at iBuildings was an Oracle podcast she did for zend.com.

Now she is giving a talk about open source stories, and she’s looking for people that are willing to recount to her how contributing to the open source movement have helped them advance in their careers. If you feel community involvement helped you get where you are, tell her your story.

Image from Wikimedia Commons


About the author—Marco is the keeper of keys and Chief Garbage Collector at Blue Parabola, php|architect's parent company. He can be found on Twitter as @mtabini.
 
 
 

Bing Powered 404 for non-WordPress websites

Posted by Cal Evans on June 17, 2010
IN Development
Tags: apache · API · bing · microsoft
 

Related Posts:

  • WordPress 404 Plugin built on Bing Wrapper
  • php|architect Podcast: 2009 in Revue
  • Transactional Emails for Fun and Profit
  • Geolocation: Easier Than It Looks
  • 2011 php|tek Webcast Series

Ok, after my last post on using the Bing Search Wrapper for handing 404 errors in WordPress I had several people tell me that while they liked the idea, they didn’t want to install WordPress just so they can have intelligent 404 errors. Several other people pinged me and suggested a way that you could use the Bing Search API to handle 404′s without WordPress. As a public service, I am going to try and bridge the gap between these two groups. Going on leads provided by friends, I have hammered out a solution that works with Apache and PHP.

Step 1: Write a 404 Handler page.

This technique is predicated on the fact that Apache lets you define your own pages for handling every error. In this example We will define a script, name it 404.php and place it in the web root.

You will notice that this is a very plain, black and white page. Feel free to decorate it to taste. The one on my personal site actually designed using my WordPress template so it matches my blog. (you can see it by clicking here, http://calevans.com/bing-rocks)

If you want to skip this step, here is a simple one, just copy and paste it. Make sure you put in your domain name and your Bing App Id

<?PHP
function __autoload($className)
{
   $fileName = strtr($className,'_',DIRECTORY_SEPARATOR).".php";
   include $fileName;
   return;
}

   $o = new Msft_Bing_Search('BING APP ID GOES HERE');
   $o->setQuery('')
     ->setWebCount(10)
     ->setSource('web')
     ->setSite('YOUR DOMAIN GOES HERE')
     ;

   $raw    = $o->search();
   $result = json_decode($raw);

?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en-US">

<head profile="http://gmpg.org/xfn/11">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

<title>calevans dot com 404 page</title>

</head>
<body>
<h3> I'm sorry, we couldn't find what you are looking for.</h3>
<p>However, here are the top 10 links from <a href="http://bing.com">Bing</a> for this site. I hope one of them is what you are looking for.</p>
<ol>
<?PHP
       foreach($result->SearchResponse->Web->Results as $value) {
           printf('<li><a href="%s">%s</a></li>',$value->Url,$value->Title);
       }
?>
</ol>
</body>
</html>

Step 2: Configure Apache

If you are not familiar with Apache config files, this one is going to be a bit tricky. The only generic advice I can give you is, back everything up, they are only text files. Unless you delete things without backups, it’s really hard to do permanent damage. Oh and if you do manage to do permanent damage, I am not responsible.

My Apache is configured with name based virtual hosts. As such I have a separate Apache conf file for each domain and all the settings go in those files. As such, inside my <VirtualHost tag I place the line:

ErrorDocument 404 /404.php

Now restart Apache and you too can type in:

http://example.com/bing-rocks

and get something that looks like this:

Or, if you are lucky enough to have a designer like the lovely and talented Kathy Then you may have something that looks like this:


About the author—Cal Evans is a veteran of the browser wars. (BW-I, the big one) He has been programming for more years than he likes to remember but for the past [redacted] years he's been working strictly with PHP, MySQL and their friends. Cal regularly speaks at PHP users groups and conferences, writes articles and wanders the net looking for trouble to cause. He blogs on an "as he feels like it" basis at Postcards from my life.
 
 
 

PHP: the teenage years

Posted by Marco Tabini on June 14, 2010
IN Opinion
Tags:
 

For some value of the word “turned,” PHP just turned fifteen. Wow.

I still vaguely remember when I turned fifteen—“rebellious,” “obnoxious” and “bad haircut” are all words that come to mind. But those were also very exciting years, full of hopes, possibilities and the knowledge that, in merely a few years’ time, I would have been able to make the roads a little less safe (in Italy, you have to be eighteen to drive, thankfully).

Milestones are not as important in our industry as they are in our lives—the way I see it, if you work in the computer field and turn to look at back at what has been, someone will have passed you by—but there are some very important lessons that can be learned from the story of PHP.

As a development project, PHP has always been a little rudderless. As a programming language, it is, on the surface, an amorphous and mismatched mass of all sorts of programming paradigms and functions that are sometimes incompatible and in conflict with one another. We have one of the best array libraries in existence—but only because the language constructs that we call arrays are not, technically speaking, arrays at all. It took two major releases to have proper object orientation. And so on, and so forth.

Purists hate PHP because, they claim, it promotes bad programming practices and is, for lack of a more accurate term, a mess. But those of us who have grown to appreciate its strengths know that PHP is like the workbench in your garage: a little messy, but filled with all the tools you may ever need to do any job imaginable. You can’t blame the workbench if you decide to drive a screw into the wall with a hammer.

As it turns fifteen, PHP and its community are like every other teenagers: sometimes lazy, sometimes brilliant, often rebellious and unfocused. The language itself has finally matured to the point where finding new functionality to add is becoming challenging and the real development work has, at least for the moment, shifted to projects that are based on PHP rather than being PHP itself. Frameworks of all complexities and sizes are thriving and occupying an ever-more-important role in our day-to-day development—although those who choose to go “naked” still have all the tools to build their applications without using anything more than what the base language provides.

Going forward, there are some real challenges. The first is going to be preventing the language from stagnating—PHP 6 is languishing to the point where so many people have worked around the issues it solves that it’s going to be difficult to continue working on it in its current state.

The other great challenge is finding a way to deal with the fragmentation that has cemented in the world of PHP frameworks. There is no clear winner in this space—even when you consider “application frameworks” like Drupal and WordPress, there are so many contenders, each with their own large community, that “supporting PHP development” is rapidly becoming a difficult proposition to make. When vendors and users decide to provide solutions for only a subset of the community, we all lose something—even those who gain the immediate benefit, because eventually they will suffer from a weakened and fragmented platform.

Happy fifteen PHP—and many returns.


About the author—Marco is the keeper of keys and Chief Garbage Collector at Blue Parabola, php|architect's parent company. He can be found on Twitter as @mtabini.
 
 
 

How I learned to stop worrying and love the wizard – Part 3

Posted by Cal Evans on
IN Development
Tags: adobe · data connection wizard · flash builder 4 · flex
 

Related Posts:

  • Flash Builder 4 training for PHP developers
  • How I learned to stop worrying and start loving the wizard – Part 1
  • Data-centric application development with Flash Builder 4
  • Mobile Development with PHP
  • Callbacks in ActionScript

In part 1, we discussed how to use the new Flash Builder 4 Data Connection Wizard to connect to a PHP API. We used FB4′s prototyping feature to build a simple class that allows us to read/write users from a WordPress user list. In part 2, we discussed how to use that data connection to ease building data-centric applications. For both of these however, we used the simple prototype class that we generated. It is also possible to use your own code to do the same thing as long as you understand what needs to be there. In this, part 3, we will write a simple class and use it with the Data Connection Wizard.

Before all else, write the code

To keep this simple, I will follow the same rules as before, I will not attempt to add or delete users, just list them and then allow them to be edited. We will call our class WPUser.

As before, for Flex to be able to inspect it, it has to be within the webroot of your project.

class WPUser
{

    protected $db;

    /**
     * @return void
     */
    public function __construct()
    {
        $this->db = mysqli_connect('localhost','root','','wpmu');
        return;
    }

When we create the class, let’s go ahead and create a connection to the database. Let me make a couple of notes here for those who might be concerned by that line. First, this code is running on my local machine against my test database. So yes, root is the user I use and there is no password on it. This is not a best practice. Please don’t copy and paste that code and just add your root password.

Second, if I were building a real application, I would use dependency injection to had my model a connection to the persistent data store. However, this is simple example so I am taking a few liberties. Again, please don’t copy this code verbatim and use it.

    /**
     * @return array
     */
    public function listUsers()
    {
        $stmt = mysqli_prepare($this->db, "SELECT * FROM wp_users");

        mysqli_stmt_execute($stmt);

        $rows = array();

        mysqli_stmt_bind_result($stmt, $row->ID, $row->user_login, $row->user_pass, $row->user_nicename, $row->user_email, $row->user_url, $row->user_registered, $row->user_activation_key, $row->user_status, $row->display_name, $row->spam, $row->deleted);

        while (mysqli_stmt_fetch($stmt)) {
            $row->user_registered = new DateTime($row->user_registered);
            $rows[] = $row;
            $row = new stdClass();
            mysqli_stmt_bind_result($stmt, $row->ID, $row->user_login, $row->user_pass, $row->user_nicename, $row->user_email, $row->user_url, $row->user_registered, $row->user_activation_key, $row->user_status, $row->display_name, $row->spam, $row->deleted);
        }

        mysqli_stmt_free_result($stmt);
        mysqli_close($this->db);

        return $rows;
    }

Ok, our listUsers() function is next. If you are paying attention, you will notice that it looks a lot like the one in the prototype class that FB4 generated. That is because it is good example code so why re-write it? The important thing to note here is the docBlock comment at the top. FB4 doesn’t actually know anything about PHP code. Instead, it relies on the docBloc comments to figure out parameters and return types.

To show the results of incorrect settings in a docBlock, I’ve changed the return value to string for listUsers()

    /**
     * @return array
     */
    public function listUsers()

Now, trying to attach our data grid to our new WPUser class will show this error:

You can see that the return type for listUsers() is now reported as String even though I’ve not actually changed the code. Since string is not an acceptable return type for a DataGrid to process. So make sure the docBolcs are not only correct, make sure that the return value you are specifying is valid for the intended use.

Now, let’s look at the code for fetchUser(). This method shows us how to specify a parameter sot ha FB4 can pick it up.

    /**
     * @param int $id
     * @return array
     */
    public function fetchUser($id)
    {
        $stmt = mysqli_prepare($this->db, "SELECT * FROM $this->tablename where ID=?");
        mysqli_stmt_bind_param($stmt, 'i', $id);
        mysqli_stmt_execute($stmt);
        mysqli_stmt_bind_result($stmt, $row->ID, $row->user_login, $row->user_pass, $row->user_nicename, $row->user_email, $row->user_url, $row->user_registered, $row->user_activation_key, $row->user_status, $row->display_name, $row->spam, $row->deleted);

        if(mysqli_stmt_fetch($stmt)) {
            $row->user_registered = new DateTime($row->user_registered);
            mysqli_close($this->db);
            return $row;
        } else {
            mysqli_close($this->db);
            return null;
        }
    }

Again, making sure you get these correct is the secret to making sure the docBlocs are correct.

Rounding out our WPUser class is the update() method. This takes as a parameter a stdClass. Behind the scenes, FB4 is using Zend_Amf (Remember when we installed Zend Framework?) to communicate with PHP using the Action Message Format. This allows it to serialize classes in FB4 pass them to PHP and unserialize them.

    /**
     * Updates the passed item in the table.
     *
     * Add authorization or any logical checks for secure access to your data
     *
     * @param stdClass $item
     * @return void
     */
    public function update($item) {
	$stmt = mysqli_prepare($this->db, "UPDATE $this->tablename SET user_login=?, user_pass=?, user_nicename=?, user_email=?, user_url=?, user_registered=?, user_activation_key=?, user_status=?, display_name=?, spam=?, deleted=? WHERE ID=?");
	throw new Exception(mysqli_errno($link), mysqli_error($this->db));

	mysqli_stmt_bind_param($stmt, 'sssssssisiii', $item->user_login, $item->user_pass, $item->user_nicename, $item->user_email, $item->user_url, $item->user_registered->toString('YYYY-MM-dd HH:mm:ss'), $item->user_activation_key, $item->user_status, $item->display_name, $item->spam, $item->deleted, $item->ID);
	throw new Exception(mysqli_errno($link), mysqli_error($this->db));

	mysqli_stmt_execute($stmt);
	throw new Exception(mysqli_errno($link), mysqli_error($this->db));

	mysqli_stmt_free_result($stmt);
	mysqli_close($this->db);
	return;
    }

}

Changing out Data Connections

Now that we’ve created a class that we can hook a Data Connection to, let’s setup our application to use the new one instead of the old one. Follow the instructions in part 1 of the article with one exception. Do not have it generate a sample class. Instead, click the Browse button and find the WPUser.php you just created. Once you do, the wizard should look something like this:

If everything looks correct, go ahead and press Finish and you will see the new Data Service in the Data Services panel.

To make it the data service for your Data Grid, click on the grid. A small icon will appear in the upper left corner like this:

Clicking on that icon will bring up a dialog that will allow you to select WPUser service. Once you do that it will need to test the call and gather information on the return value. Clicking on the “Change return type…” link (as highlighted below) will bring up a dialog that will walk you through the two steps for automatically discovering and setting the return type.

Once you’ve done that, your data grid will now be using the WPUser data service instead of the original Wpusersservice service.

Wrapping it up

I’ve attempted to give you a taste for the different things that the Data Connection Wizard can do for you when working with PHP files. In the right hands, it is a powerful tool and can save developers time and headaches. However, there are some limitations you have to be able to work with to use it.

The main one, as I’ve pointed out and discussed in previous articles, is that all of your PHP code has to be accessible in your web root. FB4 will attempt to explore your code to analyze it but it does so by opening each file and reading it as opposed to using PHP’s native reflection methods to gather this info. This isn’t a problem as long as you realize it.

In a future article we will examine the alternative to using the PHP Data Connection Wizard, the HTTP Data Connection Wizard.

…and yes, I still dislike Harry Potter. Not as a person mind you. Wizards in real life as well as in fiction tend to annoy me. I don’t like magic when it comes to my code, I want to see what is going on.


About the author—Cal Evans is a veteran of the browser wars. (BW-I, the big one) He has been programming for more years than he likes to remember but for the past [redacted] years he's been working strictly with PHP, MySQL and their friends. Cal regularly speaks at PHP users groups and conferences, writes articles and wanders the net looking for trouble to cause. He blogs on an "as he feels like it" basis at Postcards from my life.
 
 
 

The state of PHP 5.3 support

Posted by Marco Tabini on June 9, 2010
IN News
Tags: fedora · linux · mac · opensuse · php · php 5.3 · ubuntu · windows
 

Related Posts:

  • PHP 5.3.3 and 5.2.14 are out
  • PHPDOCX: generating Word documents from PHP
  • PHP 5.3 namespaces for the rest of us
  • Fat-Free, a new PHP framework
  • Zend Framework 1.10.2, and a glimpse at 2.0

PHP 5.3 introduced namespaces and anonymous functions to the PHP world, which are surely great innovations for this programming language. For PHP 5.3 to be widely used, however, it needs to be supported by the various operating systems installed on development boxes and servers.

Linux distributions

The Linux environment commonly offers open source software in the form of binary packages available via repositories, being them in the form of .deb or .rpm files. The major distributions compile and bundle every new release of their bundled softwares, and upload the resulting binaries to a public repository which makes upgrading all installed software as simple as typing sudo apt-get update && sudo apt-get upgrade.

PHP is not an exception, and it was usually present in the official repositories of distributions since its 4.x branch. Having PHP 5.3 packages instead of 5.1 or 5.2 in the official repositories is an implicit guarantee of compatibility, and is preferrable to the addition of external sources which may become out-of-date or raise conflicts. The alternative to using binary packages is compiling PHP from source code, a solution that can be time consuming and difficult for a beginner.

In their latest release, some distributions have jumped on the 5.3 bandwagon and now include binary packages of PHP 5.3. Ubuntu Linux is the leader distribution here with PHP 5.3.2, while Fedora Constantine (and Goddard) and openSUSE 11.2 follow with 5.3.0. Ubuntu probably made the right choice by jumping to 5.3 with the release of Lucid Lynx last April. Lucid is a Long Term Support release, whose updates will be provided until 2013 in Desktop Edition and 2015 in Server Edition.

Other distributions are experiencing a slower adoption – Debian and RedHat has PHP 5.3 available only in their testing branches and not in stable releases. If you are stuck with a distro without official packages for PHP 5.3, you may consider installation from an external reliable repository like Zend Server’s one (available for free in its Community Edition).

Windows

On the Windows platform, the situation is a bit different. Windows machines do not employ repositories for distributing software, but in turn there is only one bloodline of Windows to support and not a multitude of distributions.

In fact, binary packages for PHP 5.3 are available on the official windows.php.net website, and independent vendors like WampServer and EasyPHP, which provide the full software stack from Apache to PHP and MySQL, have already upgraded to PHP 5.3.0 in stable releases.

Mac

Mac OS 10.6 Snow Leopard comes with PHP 5.3 bundled, but there are also other options to install a customized version of PHP 5.3, for example to cherry-pick core extensions or to run it on a previous version of Mac OS X.

The simplest solution is to use MacPorts, which simplifies very much the process of compiling and installing open source software on the Mac platform. Currently the MacPorts version of PHP is 5.3.2 and provides separate packages for extensions. Its usage from the command line is similar to Linux’s repositories model. Another option is instead to run a full stack platform like in Linux and Windows cases: MAMP is probably the most popular choice, and it provides both PHP 5.3 and 5.2.

Desktop vs. Server

Desktop machines are much more susceptible to change than their server equivalent, especially than the shared hosting services which made the fortune of PHP all over the world. Despite this, Linux distributions and open source PHP frameworks push for upgrading to PHP 5.3 as soon as possible, while system administrators must maintain a stable environment in their production machines and need to balance the performance and feature improvements with the compatibility breaks.

PHP 4 is sometimes still spotted on production servers now, after six years from the release of PHP 5.0.0 and almost two after its end of life — given that painful experience hopefully PHP 5.3 will be embraced more quickly.


About the author—Marco is the keeper of keys and Chief Garbage Collector at Blue Parabola, php|architect's parent company. He can be found on Twitter as @mtabini.
 
 
 

PHP tours Europe in fall

Posted by Jordi Roura on June 8, 2010
IN News
Tags: community · Conference
 

Related Posts:

  • Check it out, tek 11 schedule is up!
  • Open source life style
  • phpDay 2010
  • php|tek’s Call for Papers is Closing Soon
  • php|architect Announces the First Annual Impact Awards

ElePHPant at the Barcelona conferenceIf you wanted to take PHP’s pulse, take its temperature and measure the pressure in its veins one great place to look would be the calendar of PHP-related events around the world.  And if you did that, it would seem that PHP is entering its spring!  At street level user groups are bustling with activity and keeping brewers in good business, beginners get more and better information to chew on and thus learn faster and are better prepared, and conferences congregate larger crowds to hear from the finest and brightest minds in the industry on the latest evolution of PHP development and its neighbor technologies.  And not only that, but the “fauna” that populates these events is so rich and varied that the debates that spark from them contribute to keep the wheel spinning.  Is it any wonder that they are so popular?

And that is why this fall is so special!  The 10th anniversary of the International PHP Conference will turn Germany’s Mainz into the world’s PHP capital and the fun then moves onto the sunny shores of Barcelona where palm trees and sun add a very interesting spice.  Calling all speakers!  Calls for papers open!

The International PHP Conference

The International PHP Conference has recently opened its call for papers for its 10th anniversary edition, and in its announcement it makes it very clear that it’s going to be one hell of a show.  Ten years is a long time and if the other nine conferences have been superb events, this one is going to be a real cracker.  In fact, they haven’t even waited for the summer edition to end before announcing their fall event!  Scheduled for the 11th to the 13th of October it will draw together the finest and most admired, as well as the most passionate and eager.  Feel like hitting the stage?  Now’s your chance to submit and compete for a place in an amazing three-day schedule!

The PHPBarcelona Conference

The PHPBarcelona Conference is an event run by the PHPBarcelona user group, and it shows in all the little details.  It started off as a small half-day event and, reaching its fourth edition, there is no doubt regarding its quality and potential and it has quickly become a key event in the calendar.  It’s not just about the PHP rock stars, it’s not only about the amount of talent present…  It’s about the enormous quality of its content and all the fun that speakers and attendees alike share during both days.  Looking to enjoy the last traces of summer?  Then head to Barcelona on the 22nd to the 23rd of October. Their call for papers is also open!

So, if you have something to say and only need a stage to say it on, head for Europe this fall and get your message in the streets!


About the author—
 
 
 

Zend Framework 2.0 inches closer to completion

Posted by Joel Clermont on June 7, 2010
IN News
Tags: frameworks · Matthew Weier O'Phinney · zend framework · zend framework 2.0 · zf · zf 2.0
 

Related Posts:

  • Zend Framework 1.10.2, and a glimpse at 2.0
  • Zend Framework 1.9.8 and 1.10.3 released
  • Contributing to Zend Framework
  • 5 PHP frameworks you should check out
  • Welcome to Codeworks, Matthew Weier O'Phinney!

It has been a while since we’ve received any significant news in regard to Zend Framework 2.0. The last time we discussed it on the php|a blog was back in March. However, this week saw the release of several new announcements from Matthew Weier O’Phinney, project lead for Zend Framework.

First, O’Phinney announced the new roadmap published on the Zend Framework wiki. This new roadmap reaffirms that version 2.0 will focus less on new features and more on refactoring, improved code unification, and performance. In Matthew’s words: “The primary thrust of ZF 2.0 is to make a more consistent, well-documented product, improving developer productivity and runtime performance.” This is good news for anyone that uses Zend Framework regularly.

Another exciting development is that ZF2.0 will be developed in a Git repository, instead of Subversion. In addition to the official Zend Framework 2.0 Git repository, several mirrors exist on Github as well. One of the goals of the move to Git is to make it easier for individuals to contribute code to the project, as Git’s distributed nature will allow this to happen more efficiently. There is even talk of establishing a more formal community review team.

Accompanying these announcements was a renewed call for developer assistance. Part of the conversion to 2.0 involves using the new namespaces feature in PHP 5.3 and, while many components have already been converted, there is a need for developers to jump in and help with the remaining work. In the Git repository, the current state of this conversion is tracked in the README-DEV.txt file. If there’s a component you rely on, especially in the Zend_Service part of the framework, make sure to check its status. Any component not “adopted” by someone runs the risk of getting marked as obsolete and not making it into the 2.0 release.

If you’re interested in helping out, or just want to keep closer tabs on development, head on over to the mailing lists page on the wiki and subscribe to the contributor list.


About the author—Joel Clermont is a programmer by day, and often by night. While PHP is his first love, he also regularly works with .NET and the iPhone. He is a founding partner of Orion Group, a Milwaukee web development firm, and also organizes the Milwaukee PHP user group.
 
 
 

Callbacks in ActionScript

Posted by Cal Evans on
IN Development
Tags: actionscript · adobe · callbacks · events · flex
 

Related Posts:

  • Mobile Development with PHP
  • How I learned to stop worrying and love the wizard – Part 3
  • Learning to be Flexible
  • How I learned to stop worrying and love the wizard – Part 2
  • Flash Builder 4 training for PHP developers

This post is going to be long on code. That means that I will spinkle little text between the code blocks to explain what I am doing but the bulk of the post will be code for you to copy, paste and mangle as you see fit. If you don’t want to copy and paste everything, here is the project in an archive for you to play with. twallpaper (NOTE: This project, while it compiles, is incomplete. Stay tuned for future updates.)

Callbacks rock in ActionScript

I am the first to admit that I am still trying to get my head around the concepts behind event driven programs. I’ve been knee deep in web for so long that a lot of these concepts are still not coming to me. One of the problems I am facing is how to different components, that know nothing of each other, talk to each other? Also, with asynchronous tasks taking place, how does component A know that component B has completed it’s task. The answer to both of those questions is ‘callbacks’.

In PHP we use the Observer pattern in cases to solve problems. Callbacks are an implementation of the Observer pattern in that one component tell another component, “tell me when you are done” or “tell me when something changes”.

My current project

I want to write an AIR program that looks at the twitter stream, searches for images, (I’ll use yfrog but you can easily add twitpic or any others) caches them locally and then puts them up on the screen with a nice little animation. What I have right now is a very ugly application that fetches the last 20 tweets that mention yfrog.com. The point of this milestone was to show that I could separate the logic into classes and have the classes talk to each other.

TweetFetch

Ok, here comes the first batch of code. This is the main class that talks to twitter. It is in no way a complete twitter API wrapper for ActionScript. It simply calls the search, stores the results and processes callbacks.

package com.calevans
{
	import mx.rpc.events.FaultEvent;
	import mx.rpc.events.ResultEvent;
	import mx.rpc.http.HTTPService;
	import mx.controls.Alert;
	import mx.collections.ArrayCollection;

/*
 * Fetchs all the images in the current timeline.
 */

	public class TweetFetch
	{
		protected var _service:HTTPService;
		protected var _data:ArrayCollection;
		protected var _responseCallbacks:Array;
		protected var _faultCallbacks:Array;

		public function TweetFetch()
		{
			trace('TweetFetch');
			this._service = new HTTPService();
			this._responseCallbacks = new Array();
			this._faultCallbacks = new Array();
			this._service.url = 'http://search.twitter.com/search.atom';
			this._service.addEventListener(ResultEvent.RESULT, response );
			this._service.addEventListener(FaultEvent.FAULT, fault );
			this._service.showBusyCursor=true;
		} // public function TweetFetch()

		public function fetch(query:String):void
		{
			trace('TweetFetch::fetch');
			var params:Object = new Object();
			params['q'] = query;
			this._service.send(params);
			return;
		} // public function fetch(query:String)

		public function response(response:Object):void
		{
			trace('TweetFetch::response');
			this._data=response.result.feed.entry;
			if (this._responseCallbacks.length>0) {
				for (var i:int=0;i0) {
				for (var i:int=0;i<this._faultCallbacks.length;i++) {
					this._faultCallbacks[i](e);
				}
			} else {
				Alert.show(e.toString());
			}
		} // public function myfault(e:FaultEvent):void

		public function registerResponseCallback(f:Function):void
		{
			trace("TweetFetch::registerResponseCallback");
			this._responseCallbacks[this._responseCallbacks.length] = f;
			return;
		} // public function registerResponseCallback(f:Function):void

		public function registerFaultCallback(f:Function):void
		{
			trace("TweetFetch::registerFaultCallback");
			this._faultCallbacks[this._faultCallbacks.length] = f;
			return;
		} // public function registerFaultCallback(f:Function):void

	} // public class TweetFetch

} // package com.calevans

One of the first things I hope you notice is all the trace() calls. Because we are dealing with events and async processes, I find it easier to understand what is going on if I put a trace at the beginning of each method. That way I can actually see the order of execution.

The code above works. It worked about 5 minutes after I wrote it (I did have a couple of errors working with the API) but I didn’t understand how to hook it back into the main application. That is when I started reading up on callbacks.

Functions are objects…just like everything else

One big difference between PHP and ActionScript (and I beleive JavaScript) is that functions are objects in ActionScript. This means that I can pass a function as a parameter. I’ve not investigated deeply but I beleive these are passed by reference and not by value. Therefore, I can not only pass a function in as a parameter of another function, I can store that function reference, pass it around and even call it. That, in my book, is pretty dang cool. (I am easily amused)

You will see in the cod above a function registerResponseCallback() (and it’s conunterpart registerFaultCallback()) As the name says, this is were you tell TweetFetch what to do once it has successfully fetched and stored the tweets. I will show the full twallpaper.mxml later, for now, here is the snippet form it where I actually register a callback.

tweetFetch.registerResponseCallback(processNewTweets);

It is that easy, well almost. There are a couple of things you need to know. First, obviously processNewTweets() needs to exist. Second, it need to accept the proper parameters. In this case, when the callbacks are processed, they will each be called, passing in an ArrayCollection so processNewTweets() has to accept a single parameter of an ArrayCollection.

fetch() at line 32, is the main function of this method. Calling hat with a query will set things into motion. It makes the call to the HTTPService. When HTTPService returns successfully, it fires result(). result() stores a subset of the result that comes back from twitter and then looks to see if there are any registered callbacks. If there are, it calls them with this line:

this._responseCallbacks[i](this._data);

this._responseCallbacks[i] this contains the pointer to the function. (this._data) This is the parameter list to pass in. This is what I meant about callbacks being cool, it is that easy.

Do the deed

Ok, you understand the code, you see now how to create a callback that TweetFetch can fire so that the interface can be updated as things happen. Here now, is the main twallpaper.mxml so you can see how I put it all together.

<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
					   xmlns:s="library://ns.adobe.com/flex/spark"
					   xmlns:mx="library://ns.adobe.com/flex/mx" creationComplete="init(event)">
	<fx:Declarations>
		<!-- Place non-visual elements (e.g., services, value objects) here -->

	</fx:Declarations>
<fx:Script>
	<![CDATA[
		import com.calevans.TweetFetch;
		import mx.events.FlexEvent;
		import mx.collections.ArrayCollection;
		import mx.rpc.events.FaultEvent;
		import mx.controls.Alert;

		public var tweetFetch:TweetFetch = new TweetFetch();

		protected function init(event:FlexEvent):void
		{
			trace('init');
			tweetFetch.registerResponseCallback(processNewTweets);
			tweetFetch.registerFaultCallback(oops);
		}

		public function mainButtonClick():void
		{
			trace('mainButtonClick');
			tweetFetch.fetch('yfrog.com');
		}

		protected function oops(e:FaultEvent):void
		{
			trace('oops');
			Alert.show(e.toString());
			return;
		}
		protected function processNewTweets(data:ArrayCollection):void
		{
			trace('processNewTweets');
			for(var i:int=0;i
</fx:Script>
	<s:Button x="251" y="83" label="Button" click="mainButtonClick()" />
	<s:TextArea id="myTextArea" x="0" y="125" width="573" height="490"/>
</s:WindowedApplication>

I have said it before but I will reiterate it this is prototype code. The current interface is only to show that TweetFetch is working. So yes, it’s ugly. It does show that the underlying code is working however and it shows a very simple example of callbacks.

One note, I have implemented callbacks for faults as well. Just to show that they are working, I added the function oops() that simply pops an alert box, the same behavior that happens if there is no registered callback. This is just to show the functionality, neither oops(), nor the Alert box will survive into the final code.

Wrapping it up

The problem I had in this particular instance was, how do you update the interface when an async task in an object completes. In my previous examples, all my code was in the main mxml for ease of understanding but as I began to move things out into classes and began to normalize my application, I found new problems presenting themselves. Events, which I will talk about in another post, and callbacks make solving those problems very easy. As this starts to sink into to my web-soaked brain, things start to make sense.


About the author—Cal Evans is a veteran of the browser wars. (BW-I, the big one) He has been programming for more years than he likes to remember but for the past [redacted] years he's been working strictly with PHP, MySQL and their friends. Cal regularly speaks at PHP users groups and conferences, writes articles and wanders the net looking for trouble to cause. He blogs on an "as he feels like it" basis at Postcards from my life.
 
 
 

This month's issue

January 2012
Buy · $5 — Subscribe · starts at $35
 

 

Upcoming Training Courses

Course Start Date
Essential PHP 2012-02-03
AJAX Programming with PHP and … 2012-02-10
Essential Zend Framework 2012-02-17
Mobile HTML5, JavaScript and P… 2012-03-02
Professional PHP Development 2012-03-09
 

About us

  • What we do
  • Contact us
  • Write for us

Policies & legal

  • Customer support
  • Privacy policy
  • Refund policy
  • Terms & Conditions

Online Store

  • Magazine
  • Training courses
  • Books

Special sections

  • Codeworks 2011
 

Copyright © 2002-2012 Blue Parabola, L.L.C. — All amounts in USD - WP3