Usage of Zend_Http_Client is pretty straight-forward:

$client = new Zend_Http_Client($uri);
$client->request(Zend_Http_Client::HEAD); // HTTP HEAD request

However, today, on my Ubuntu box I had real problems as HTTP client constantly ended in segmentation fault (SIGTERM in apache logs). When debugging, I noticed that it does so only if $uri contains so called «unwise» characters, such as spaces, «{«, «}», «^» etc.

Going deeper, I reviewed the source code of Zend_Http_Client::setUri($uri) method, only to discover that it relies on Zend_Uri::factory($uri), to initialize the URLs. From there it was pretty simple. Zend_Uri is aware of «unwise» chars problem and disallows them by default (why exception thrown by Zend_Uri ended in SIGTERM is yet to discover, however). In order to allow such a characters:

Zend_Uri::setConfig(array('allow_unwise' => true));
$client = new Zend_Http_Client($uri); // $uri may contain unwise chars now

After issuing above instruction Zend_Uri accepts those unwisely formed URIs. Plus, you have to URL-encode white-spaces (i.e. make sure that white-spaces in query string, or actually in URI part after the host name are replaced with «%20″ char) to make them acceptable.

Further info available in offical documentation.

Please note, that I still think that having unreliable chars in URI is really bad practice. If you work with some system that already gone far on this path, it’s nice to have a method to actually consume such a wildly formed URIs. Kudos to Zend_Uri maintainers!

,

I have used ZF in several projects, and think is is quite safe to use svn:externals to attach Zend and ZendX as external dependency. It might not be the good idea for other projects, but when it comes to ZF – what is in trunk is pretty stable.

So, go into folder which stores ZF, and safely remove the library. Then just add ZF as external dependency (which would be updated every time you update the working copy):

svn pe svn:externals .

in and editor opened, enter the dependencies:

Zend http://framework.zend.com/svn/framework/standard/trunk/library/Zend
ZendX http://framework.zend.com/svn/framework/extras/trunk/library/ZendX

finally commit everything and obtain.

svn ci -m 'ZF set as external dep'
svn up

The beauty of this approach – you always have up to date version of ZF.
The danger of this approach – you always have up to date version of ZF!

Word of caution:
Sometimes this may break things (when backward-compatibility is broken in ZF trunk), but actually if you have unit tests which check your build before deploying, you are pretty safe – you spot the problem, you resolve it.

NB: This approach supposes that you tag your releases, so that when new release is coming out, you create a tag, export everything into newly created tag (thus freezing the code), and checkout from tag on production server.

,

I have finally completed proposal for Authorize.net CIM API. Hopefully, this API gets included into ZF (in one form or another), as ANet is one of the best services to work with user payment profiles, let alone CC processing. On proposal page you can review use cases, and if you are interested in internals feel free to download fully-working component’s prototype (it is still a prototype as most probably it would be updated in accordance with peer review on ZF wiki).

Let me know your suggestions on how the component can be improved.

,

This seems kind of limitation to me, indeed, if you use __toString() magic method for anything other than simple object variables concatenation, your code should be able to throw exceptions. Consider you have an object that generates XML as output, and you decide to provide even nicer interface, so that anyone using it in string context to get access to that XML. XML generation might not go well, and the obvious way to let the client know about this is to throw an exception. However, this is not possible (most probably due to some internal architecture limitations – as I honestly see no reason why this ideologically wrong).

One (not quite pretty) way to still provide some feedback from __toString() is using trigger_error:

public function  __toString()
{
    try {
        $output = $this->generateXml();
        return $output;
    } catch(Exception $e) {
        trigger_error($e->getMessage(), E_USER_ERROR);
        return '';
    }
}

If you know of a better option, let me know!

,

Starting with PHP5 almost any PHP installation contained SPL (Standard PHP Library) extension – with few exceptions, when hosters intentionally disabled it. With PHP 5.3 out, this extension is considered to be within PHP core, and as such it’s not possible to disable it anymore. This in fact is a good thing, as SPL really deserves to be the core component.

In an attempt to shed some light on and to draw attention to SPL, I plan to post several articles discussing various parts of this extension. I will start with SPL Interfaces so that you can grasp immediately the usefulness of the SPL.

Comprehending SPL interfaces presupposes that you know standard interfaces that come build-in with PHP5. So, I wrote preliminary article discussing them – I consider it to be a prerequisite for good understanding of the current material.

Covered in this article:

Read the rest of this entry

, ,

Note: This article serves as preliminary for SPL Interfaces article to be published later on.

I wanted to provide good overview of (highly under-used) Standard PHP Library (SPL) starting with interfaces. However, without firstly discussing predefined interfaces, which come bundled with each and every PHP distribution, discussion of SPL-provided ones seemed to be incomplete.

To be covered in this article:

Read the rest of this entry

, ,

Rendering view script for particular controller action is really easy. Indeed, thanks to (enabled by default) ViewRenderer helper, scripts are auto-loaded: renderer searches script directory(ies) for a view script called CONTROLLER_NAME/ACTION_NAME.SCRIPT_EXTENSION once found, view is auto-rendered.

However, sometimes it’s not what you want, instead you need to render some other view depending on some internal criteria. For example, you may want to render some custom error displaying view. So, if we are positive on what we want, let me show you how to do it:

class TestController extends Zend_Controller_Action
{
    /**
     * test/index.phtml would be rendered by default
     * @return void
     */
    public function indexAction()
    {
        // render test/foo.phtml
        $this->_helper->viewRenderer('foo');

        // render bar/foo.phtml to the default response segment, without using a
        // controller view script subdirectory ("test" in this case):
        // so you may use scripts from other controllers
        $this->_helper->viewRenderer('bar/foo', null, true);

        // now render the script, as previous calls do not render anything,
        // they are just used so that default script is swapped and not rendered:
        $this->render('foo');
        // OR
        $this->render('bar/foo', null, true);
    }
}

Please, note that you do not need to provide view extension (foo but not foo.phtml or any extension you happen to use for your views) – what renderer expects is action name, and we simply swapping the current action. Internally, direct() method is called when you update view renderer, which in turn is proxy for setRender():

// allows you to set any of scriptAction, responseSegment,
// and noController in one pass.
setRender($action = null, $name = null, $noController = false)

So, you may use

$this->_helper->viewRenderer->setRender('foo');

to change current view, but this form is less common, as it requires more typing :)
NB: If you need more info on ViewRenderer there’s no better place but ZF Manual.

Sometimes, especially when dealing with variations of factory pattern, single method (namely factory()) can return objects of different types, so NetBeans is unable to guess the exact type of returned instance and as such cannot auto-complete. Indeed, you can setup return type using phpDoc syntax:

/**
 * @return Some_Base_Abstract_Class_Name
 */
public function factory($adapter)

but that doesn’t work if returned objects are specifications of more general abstract class (exactly the case with factory).

As it turned out, you can easily resolve this issue – just document your variable with @var, before calling factory() method:

/**
 * @var Some_Specific_Class $foo
 */
$foo = Magic::factory('adapterName');
$foo-> // and NetBeans opens pop-up list with available attributes and methods

The good news, you can use this method in any scope – it just works :) I love NetBeans!!

UPD: Well, actually NetBeans seems to be picky of scope – as reported by others (and confirmed by myself).

UPD1: Actually NetBeans handles this quite well, just use vdoc (review this and this for details)

,

Today, when working on UMapper plugin, I tried to use jQuery – and failed. Although jQuery is now in WP core, $ shortcut wasn’t working. As it turned out, WP team (quite rightly!) used JQuery.noConflict – which helps avoiding naming conflict with similar libraries, such as prototype. So, we cannot use $ shortcut function, which is quite annoying. In order to overcome this limitation the following construct can be used:

jQuery(document).ready(function($){
    // inside this block you can use $ shortcut !!
});

Just a small note to myself :)

,

Zend Framework (ZF) is the MVC framework. Of course you can use its components in a non-MVC way (and I actually do so in my WP UMapper plugin), but in that case, I suppose, you do not have to worry about models auto-loading.

Frameworks make our coding life easier, and ZF is not an exception – you need very little code to get your application skeleton working. And when it comes to MVC, ZF handles almost everything – your action controllers are triggered, your views are loaded, w/o you having to worry about them. Not the same with models. If you comply to directory layout advised by ZF, you have «models» folder, but framework doesn’t interact with it in any way.

Models are simply classes, containing application logic, and to initialize one of them you have to make sure that:
a) containing directory is withing include_path
b) you require_once the class file before using it

I wanted my models to be available without any additional hassle, so I decided to find a way to auto-load models from within my controller actions.

Read the rest of this entry

, ,