Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Variable Empty until Reassigned

Tags:

php

I am not quite sure why this is happening, or how to properly explain it, but maybe someone can shed some light on this.

I have a CMS system I based off of the CodeIgniter/Opencart Framework utilizing a Registry, Controller and Module. I have run into a scenario where I have previously saved a variable to the registry as:

$this->application_page = 'current/page';

But for some reason when I call it in the application:

echo empty($this->application_page)?'yes':'no';
//Returns Yes

But.. When I Reassign it:

echo empty($this->application_page)?'yes':'no';
//Returns Yes

$page = $this->application_page;
echo empty($page)?'yes':'no';
//Returns No

A var_dump returns:

var_dump($this->application_page);
string 'current/page' (length=12)

I can get around this quite easily by just using $page but I'm curious to know why this is happening?

UPDATE:

So I messed around with the _isset function but didn't get it to work, possibly my error, possibly not.. Here is how it all works together:

class Registry {
  private $data = array();
  public function get($key){ return (isset($this->data[$key]) ? $this->data[$key] : NULL); }
  public function set($key,$val){ $this->data[$key] = $val;
}

abstract class Controller {
  protected $registry;
  public function __construct($registry){ $this->registry = $registry; }
  public function __get($key){ return $this->registry->get($key); }
  public function __set($key,$value){ $this->registry->set($key, $value); }
}

class Applications {
  private $registry;
  function __construct($Registry){ $this->registry = $Registry; }
  function __get($key){ return $this->registry->get($key); }
  function __set($key,$val){ return $this->registry->set($key,$val); }
  public function buildApplication(){
      $this->application_page = 'current/page';
      $application = new application($this->registry);
  }

}

class Application extends Controller {
  public function index(){
    echo empty($this->application_page)?'yes':'no';
    //Returns Yes

    $page = $this->application_page;
    echo empty($page)?'yes':'no';
    //Returns No
  }
}

Hopefully this helps? Had a Typo, Registry's functions are not magic methods. Also $registry was declared in Applications.

like image 618
Corey Avatar asked Oct 03 '22 08:10

Corey


1 Answers

The class probably didn't implement the magic __isset() method which is triggered by calling isset() or empty() on inaccessible properties.


Example:

Live demo I:

<?php

class Test {
    private $a = '42';

    public function __get($name) {
        return $this->a;
    }
}

$obj = new Test();
var_dump($obj->a);        // string(2) "42"
var_dump(empty($obj->a)); // bool(true)

Implementing the __isset() method as follows (Live demo II) will yield the correct result:

public function __isset($name) {
    if ($name == 'a') {
        return true;
    }
    return false;
}

// ...
var_dump($obj->a);        // string(2) "42"
var_dump(empty($obj->a)); // bool(false)


Here is a new version of your code implementing the __isset() methods: http://ideone.com/rJekJV

Change log:

  • Added __isset() method to Controller class which internally calls Registry::has().
  • Added has() method to Registy class.

  • [Only for testing: Object initialization and running Application::index() method.]

There was one issue (after updating your answer):

  • You haven't declared $registry as a member variable in the Applications class.
    The code fails otherwise because it doesn't access the actual member variable (magic __set() method!)

  • Also, you had quite some redundancy in your code (not DRY). I hope this isn't production code ;)

like image 134
ComFreek Avatar answered Oct 07 '22 22:10

ComFreek