Issues

ZF-7107: Zend_Validate_Http outputs "unsupported operand type" error when running PHP in interactive mode

Description

Attempting construct a Zend_Uri in an interactive PHP console fails with an "unsupported operand type" error:

$ php -a
Interactive shell

php > require_once('Zend/Uri.php');
php > Zend_Uri::factory("http://www.google.com");
PHP Fatal error:  Unsupported operand types in .../library/Zend/Validate/Hostname.php on line 469
PHP Stack trace:
PHP   1. {main}() php shell code:0
PHP   2. Zend_Uri::factory() php shell code:1
PHP   3. Zend_Uri_Http->__construct() .../library/Zend/Uri.php:130
PHP   4. Zend_Uri_Http->valid() .../library/Zend/Uri/Http.php:154
PHP   5. Zend_Uri_Http->validateHost() .../library/Zend/Uri/Http.php:281
PHP   6. Zend_Validate_Hostname->isValid() .../library/Zend/Uri/Http.php:449

Oddly enough, this works just fine when executed inside of a .php file.

Digging through past versions, it seems this behavior didn't start until ZF 1.8.0.

Comments

What version of php are you on (in CLI mode)?

$ php --version PHP 5.2.9 (cli) (built: Jun 22 2009 18:51:54) Copyright (c) 1997-2009 The PHP Group Zend Engine v2.2.0, Copyright (c) 1998-2009 Zend Technologies with Xdebug v2.0.4, Copyright (c) 2002-2008, by Derick Rethans

This is interesting:

I've looked into the source code and this error is in my understanding impossible :-)

Checked against trunk... lines are +1 Line 470 (old 469):


                            $regexChars += $this->_validIdns[strtoupper($this->_tld)];

*1*                    $this->_tld = strtolower($matches[1]);
                    if ($this->_validateTld) {
                        if (!in_array($this->_tld, $this->_validTlds)) {
                            $this->_error(self::UNKNOWN_TLD);
                            $status = false;
                            break;
                        }
                    }

                    /**
                     * Match against IDN hostnames
                     * Note: Keep label regex short to avoid issues with long patterns when matching IDN hostnames
                     * @see Zend_Validate_Hostname_Interface
                     */
*2*                    $regexChars = array(0 => '/^[a-z0-9\x2d]{1,63}$/i');
                    if ($this->_validateIdn &&  isset($this->_validIdns[strtoupper($this->_tld)])) {
                        if (is_string($this->_validIdns[strtoupper($this->_tld)])) {
                            $regexChars += include($this->_validIdns[strtoupper($this->_tld)]);
                        } else {
*0*                            $regexChars += $this->_validIdns[strtoupper($this->_tld)];
                        }
                    }

1: $this->_tld is in any case a string by using strtolower($matches[1]); Else the error/warning/notice would have been thrown in this line. So the problem is not regarding the usage of strtoupper($this->_tld) within *0*

0: $this->_validatldns is an internal array which is set in any case. So the problem can not be due to _validldsn not being an array.

2: $regexChars is in any case an array which is set. So the problem can not be the usage of += as the array is already set.

In sum: I don't see a way how a fatal error can occur within ZF1.8 / trunk.

Can you do some debugging to see where the problem comes from ?

So, I did some more digging, and I found the problem.

It seems that when running from the interactive shell, include() is always returning int(1). As a result, we're executing:

{{$regexChars += 1;}}

I've verified this behavior on several systems, as well as the latest release of PHP (5.2.10).

I'm attributing this to a problem with PHP itself. It looks like there's a bug open for this behavior in the PHP bug tracker, but it was marked as bogus (working as intended). I'm not sure why.

http://bugs.php.net/bug.php?id=48056

Since PHP Bug #48056 is closed and I can't add any comments to it, I've opened a new bug asking somebody to look into this:

http://bugs.php.net/bug.php?id=48682

Closing as not reproducable.

Feel free to reopen it as soon as you can provide us with a way how to prevent include from returning a 1 instead of the file itself in your case.

I'm seeing the same issues on 1.9.0, 1.9.1 and 1.9.2 when trying to utilize Zend_Http_Client but the errors being reported appear exactly the same and testing Zend_Uri as the original reporter did produces the same result for me.

Discovered this is a general fallacy with PHP's include function that appears to have gone awry in 5.2.9 and 5.2.10 and possibly other version. Reported as bug there.

[http://bugs.php.net/bug.php?id=49405]

I see no way how ZF can solve a problem which is related to special PHP versions. Specially when we don't know how this occurs nor how we could fix it.

Thomas is correct.

This is definitely a PHP bug, not a ZF one. Nothing further to do here.