ZF-5883: Headlink.php line 310 ksort throws error

Description

The ksort in toString on Headlink.php can cause an error Fatal error: Call to undefined method Zend_View_Helper_Placeholder_Container::ksort() in /library/Zend/View/Helper/HeadLink.php on line 310. Once commented out there are no errors.

Code calling headlink below:

    $this->headLink()->appendStylesheet('<a rel="nofollow" href="http://yui.yahooapis.com/2.6.0/build/reset-fonts-grids/reset-fonts-grids.css">http://yui.yahooapis.com/2.6.0/build/&hellip;</a>');
    $this->headLink()->appendStylesheet('/css/application.css');
    $this->headLink()->appendStylesheet('/css/filetypes.css');
    $this->headLink()->appendStylesheet('/css/iesucks.css','screen','IE');
    echo $this->headLink();

Comments

The same happens in HeadLink (line 310), HeadScript (line 449), HeadMeta (line 332) and HeadStyle (line 365). The ArrayObject does not imply ksort function and thus it cannot be called: http://uk2.php.net/manual/en/class.arrayobject.php

A temporary fix is to add a function to /Zend/View/Helper/Placeholder/Container/Abstract.php.

Set component and auto re-assign

This appears to be an issue related to the version of PHP being ran. I had this error occur when running on PHP 5.1.6.

ArrayObject implies ksort with PHP 5.2.0 and above. Though we no longer support PHP below 5.2.4, I suspect that this code has been in place for some time before 1.7.0. I'll see if I can post a patch to the issue for those using prior PHP versions.

Fatal error: Call to undefined method Zend_View_Helper_Placeholder_Container::ksort() in /home/.../library/Zend/View/Helper/HeadLink.php on line 310

To reproduce I have the following files: http://framework.zend.com/releases/… http://framework.zend.com/demos/…

The latest version of PHP with CentOS 4.7 is PHP 5.1.6, this is due to backporting (http://tinyurl.com/r77l2).

Included in the framework, the README SYSTEM REQUIREMENTS says:

Zend recommends the most current release of PHP for critical security and performance enhancements, and currently supports PHP 5.2.4 or later.

While the INSTALL SYSTEM REQUIREMENTS says:

Zend Framework requires PHP 5.1.4 or later.

Both documents point to http://framework.zend.com/manual/en/… which says:

Zend recommends the most current release of PHP for critical security and performance enhancements, and currently supports PHP 5.2.4 or later.

Although this recommends a version, it does not have a minimum requirement.

By searching the files, I found some requirements for PHP 5.2.0 or above...

findstr /s PHP_VERSION . library\Zend\InfoCard.php: $base64DecodeSupportsStrictParam = version_compare(PHP_VERSION, '5.2.0', '>='); library\Zend\InfoCard\Xml\Security.php: $base64DecodeSupportsStrictParam = version_compare(PHP_VERSION, '5.2.0', '>='); library\Zend\InfoCard\Xml\SecurityTokenReference.php: if(version_compare(PHP_VERSION, "5.2.0", ">=")) {

This is all kind of off putting for someone new to this framework, when there's no strict guidelines as to which version you're meant to use, a lack of backwards compatibility, and no basic version control error checking. Disappointing.

All this aside, looking at the actual error itself, it says that ksort() simply isn't defined, even though the PHP native function has existed since PHP 4.

On line 310 I see the following:

$this->getContainer()->ksort();

I searched the entire of the library and could not locate anywhere that defines ksort as a function within the class.

The term "function ksort" does not exist in any of the files included in the downloads, thus it's clearly not defined.

This is clearly an issue which has existed since 1.7.5 and has still to be addressed...

ksort() is defined in ArrayObject, which is an SPL class. However, it was added in the PHP 5.2.x series -- which is why the error occurs in PHP 5.1.x versions and not PHP 5.2.x versions.

I will look into why the upped version requirements are not reported in the 1.7.x release notes -- that said, it was a major part of our messaging for the 1.7.0 release.

Is there any reason why it needs to use SPL ArrayObject's ksort() over the native ksort()?

http://php.net/~helly/php/…

This seems to suggest not.

Is Zend Framework going to have any kind of backwards compatibility or am I expected to upgrade and recompile PHP to bleeding edge each time I use the latest version?

The ksort fix was put in place for ZF 1.7.5 (http://framework.zend.com/issues/browse/ZF-5435).

Jon -- if this was indeed fixed for 1.7.5, could you please mark this issue as resolved? Thanks!

Matthew,

I think I misspoke. I put the ksort code in place for 1.7.5 which caused this error on php 5.1.x. With ZF only supporting php 5.2.4 as the minimum now should a fix be put into place to make it use the native ksort instead of the SPL ksort?

Jon

grep -B 1 'PHP 5' ZendFramework-1.7.7/*.txt

ZendFramework-1.7.7/INSTALL.txt-

ZendFramework-1.7.7/INSTALL.txt:Zend Framework requires PHP 5.1.4 or later. Please see the system requirements

ZendFramework-1.7.7/README.txt-Zend recommends the most current release of PHP for critical security and ZendFramework-1.7.7/README.txt:performance enhancements, and currently supports PHP 5.2.4 or later.

I guess this could be the actual issue?

At least it fooled me into thinking I could run ZF 1.7 on a server running CentOS 5 (php-5.1.6) - Now this gives me the feeling ZF 1.7 isn't meant to be used in a production environment...

/B

So, first off, I will correct the INSTALL.txt file today to correctly reflect the minimum supported PHP version (5.2.4).

Second, as to your jab about "this gives me the feeling ZF 1.7 isn't meant to be used in a production environment", we carefully considered the benefits and pitfalls of upping the minimum supported version. At this time, the only major distributions still shipping a PHP 5.1.x version are... RHEL and CentOS. And RHEL will not be releasing a new version with an updated PHP version until sometime in 2010. 5.1.4 was released almost 3 years ago, and many improvements and fixes to the language have been released since then; to be honest, 5.2.4 was shipped over 18 months ago, and many improvements have been made since then. However, in our review of distributions -- including many Linux, *BSD, and other *nix variants -- most were shipping at that version or newer, including now Debian Lenny.

Jon -- no, do not back out the change. Since the minimum supported version supports SPL's ksort, we can use it.

Updated INSTALL.txt to correctly show minimum supported version; current ksort() usage is correct per our minimum requirements.

1, Was this a documentation issue then? 2, Will the website documentation change to say "requirement" instead of "recommend"? 3, Will there be no backwards compatibility legacy support? 4, What are the recommendations for RHEL and CentOS users? -- considering that RHEL and CentOS are very popular for production web servers. 5, Are you going to introduce any "compatibly" checks? -- this will help avoid issues like this in future.

  1. Yes -- the INSTALL.txt was out-of-date with other documentation, including our own manual and the README.txt file.
  2. The website already says that 5.2.4 is required for versions 1.7.0 and above.
  3. We will only backport security fixes to previous branches, but not bugfixes.
  4. RHEL has more up-to-date packages via its paid support channels. Additionally, a number of semi-official channels for both distros have more up-to-date PHP packages as well -- including Oracle's repositories. Finally, third party vendors such as Zend are offering supported AMP stacks that may be used with RHEL and CentOS.
  5. What sort of compatibility checks to you suggest?

Ok. (Matthew, sorry for venting my frustrations :)

I think this only is/was a documentation issue, but I also second James in adding some version checking. And since Mattew now has illuminated me, I will really consider upgrading to php 5.2 on the EL5 machines. I think the improvements would be worth it, and I think it will be less effort than "backporting" ZF to php5.1...

Bernt -- no worries. I understand the frustrations entirely. On the flip side, the fact that some distros offer no ability to upgrade PHP versions (which are actually very much BC between versions in the same major revision) is incredibly frustrating to component library and framework developers, as they prevent us from using up-to-date language features, and in effect can hamper the uptake of said features. At a certain point, we have to decide between progress of the framework and supporting all available versions -- and the latter is in many cases a Sisyphean task. (Much like supporting browser versions in Javascript and CSS...)

http://framework.zend.com/manual/en/…

Zend recommends the most current release of PHP for critical security and performance enhancements, and currently supports PHP 5.2.4 or later.

The website says "recommend" not require.


With regards to upgrading PHP on CentOS:

For CentOS 4: cd wget -q -O - http://www.atomicorp.com/installers/atomic.sh | sh yum --en=atomic update php

For CentOS 5: cd /etc/yum.repos.d wget http://dev.centos.org/centos/5/CentOS-Testing.repo yum --en=c5-testing update php


With regards to compatibly checks...

if (version_compare(PHP_VERSION, '5.2.4, '<') { die('Zend Framework is not compatibly with your version of PHP, please upgrade.'); }

@James Wade: The operative part of that sentence is "supports PHP 5.2.4 or later". That's a requirements statement. The verbiage "recommends" is related to "the most current release".

Thanks for the information on upgrading PHP on CentOS -- that will be useful for many.

As for your compatibility check... where would that go, exactly? There is no single god class in ZF that is used by every single component. While I think that the version check could be nice functionality, I hesitate to push a global dependency into the framework.

Matthew,

"supports" and "requires" are not one of the same:

I support PHP, but I do not require it; I require food, but do not support it.

The compatibility check only needs to appear in the classes that compatibility is an issue, in this case...

library\Zend\View\Helper\HeadLink.php

If this file requires 5.2.4 or above, it should check for it; otherwise as we know, it won't work.

However, what I fail to understand is that ksort was added to SPL's ArrayObject here: http://cvs.php.net/viewvc.cgi/php-src/…

By the looks of it, it was added into PHP 5.1, so why it won't work in 5.1.6 I'm not entirely sure.

I'm not seeing that this issue is closed.

I'm using a fresh download of ZendFramework 1.9 on a RHEL 5.3 machine with PHP 5.2.9 from Centos-5 Testing repo.

From the most recent Quickstart guide:

application/layouts/scripts/layout.phtml:

<?php echo $this->headLink()->appendStylesheet('/css/global.css') ?>

Puts the following error in the Apache error_log:

PHP Fatal error: Call to undefined method Zend_View_Helper_Placeholder_Container::ksort() in /var/www/library/Zend/View/Helper/HeadLink.php on line 311

I've verified that ArrayObject is present in the PHP release I'm using with the following test script:

$foo = array('a' => 'Aye', 'b' => 'Bee', 'c' => 'See'); $obj = new ArrayObject($foo); $obj->ksort();

Which seems, to me, to imply that in Zend/View/Helper/HeadLink.php on line 311:

$this->getContainer()->ksort();

$this->getContainer() is not returning a reference to an ArrayObject.

That would be a different issue I think. PHP <5.2.4 is simply not supported, and that's what this issue about. I think you should add a different issue for your point.