Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Config child class E_NOTICE on non existent element access #1315

Closed
viktoras25 opened this issue Sep 30, 2013 · 5 comments
Closed

Config child class E_NOTICE on non existent element access #1315

viktoras25 opened this issue Sep 30, 2013 · 5 comments

Comments

@viktoras25
Copy link
Contributor

So I was using Phalcon\Config class for following expressions:

if (!empty($config->some->value)) {
    die("Value does not exist");
}

And this works without any problems, which is nice. However when I try to do the same with an inherited class - I get notices "Undefined offset".

This code simulates the issue.

class C extends Phalcon\Config {}

$c1 = new Phalcon\Config();
$c2 = new C();

empty($c1->non->existing->value);
empty($c2->non->existing->value);

Notice is shown only for 2nd empty call. I'm not sure if it's a bug or restriction.

Phalcon version 1.3.0 built from ext.

@viktoras25
Copy link
Contributor Author

I presume this may has to do with

obj->obj.ce->type != ZEND_INTERNAL_CLASS

Because Phalcon\Config class is defined in extension and might be considered internal and my custom defined classes are not.

@ghost
Copy link

ghost commented Oct 2, 2013

Seems like a bug — isset() triggers the same behavior.

@ghost
Copy link

ghost commented Oct 2, 2013

Or maybe not — empty() is called only on the last component (value); PHP tries to read $c->non and $c->non->existing before trying to call empty()/isset().

Internal classes understand PHP's intention to check whether the property exists (PHP passes them a special flag) but there is no way to pass that flag to __get() method.

Here's a quick test case:

<?php

error_reporting(E_ALL);

class A
{
        private $props = array();

        public function __isset($k)
        {
                echo __METHOD__, "\n";
                return isset($this->props[$k]);
        }

        public function __get($k)
        {
                echo __METHOD__, "\n";
                return $this->props[$k];
        }
}

$a = new A;
var_dump(isset($a->b->c));
var_dump(empty($a->b->c));

PHP will complain twice about Notice: Undefined index: b — it looks like this is the standard behavior.

@ghost
Copy link

ghost commented Oct 2, 2013

I have implemented a workaround: if read_property/read_offset is called with BP_VAR_IS flag (intention to check if the property/dimension exists) and the class is a userspace class, the code will call first __isset()/offsetExists() and invoke __get()/offsetGet() only on success.

This adds one extra call on such isset()/empty() calls but will result in a cleaner code without any notices and warnings.

@ghost ghost mentioned this issue Oct 2, 2013
@viktoras25
Copy link
Contributor Author

I didn't understand much about the flag, but thank you very much :) 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant