jcubic
jcubic

Reputation: 66488

Can't delete object property in php

I have this code:

class Service {
    public function get_session($token) {
        foreach ($this->config->sessions as $session) {
            if ($token == $session->token) {
                $session->last_access = date('r');
                return $session;
            }
        }
        return null;
    }
    public function mysql_connect($token, $host, $username, $password, $db) {
        if (!$this->valid_token($token)) {
            throw new Exception("Access Denied: Invalid Token");
        }
        // will throw exception if invalid
        $this->mysql_create_connection($host, $username, $password, $db);
        $session = $this->get_session($token);
        $id = uniqid('res_');
        if (!isset($session->mysql)) {
            $session->mysql = new stdClass();
        }
        $mysql = &$session->mysql;
        $mysql->$id = array(
            'host' => $host,
            'user' => $username,
            'pass' => $password,
            'name' => $db
        );
        return $id;
    }
    public function mysql_close($token, $res_id) {
        if (!$this->valid_token($token)) {
            throw new Exception("Access Denied: Invalid Token");
        }
        $session = $this->get_session($token);
        if (!(isset($session->mysql->$res_id))) {
            throw new Exception("Invalid resource id");
        }
        unset($session->mysql->$res_id);
        if (empty((array)$session->mysql)) {
            unset($session->mysql); // this don't work, don't know why
            throw new Exception('isset($session->mysql) == ' .
                                (isset($session->mysql) ? 'true' : 'false'));
        }
    }
}

I call unset($session->mysql); if it's empty but the object is not removed, the exception throw true, How can I delete $session->mysql object? I've tried to add & in get_session but this didn't help.

Whole code can be found here.

Upvotes: 0

Views: 927

Answers (1)

Clay
Clay

Reputation: 4760

You really should have posted your Session class in your post instead of linking to your GitHub repo... that's why the comments are confusing. You are using magic methods on your session class.

1 change I made: adding the magic __unset method.

Also, I had thought the constructor needed to be public but on further looking at it I was wrong about that (so my test code will not work unless the constructor is public... anyway...).

Here is the code below with the updated class:

<?
class Session {
    public $storage;
    public $token;
    public $username;
    public $browser;
    public $start;
    public $last_access;
    private function __construct($u, $t, $s = null, $b = null, $d = null) {
        $this->storage = $s ? $s : new stdClass();
        $this->username = $u;
        $this->token = $t;
        $this->browser = $b ? $b : $_SERVER['HTTP_USER_AGENT'];
        $this->start = $d ? $d : date('r');
    }
    function &__get($name) {
        return $this->storage->$name;
    }
    function __set($name, $value) {
        $this->storage->$name = $value;
    }
    function __isset($name) {
        return isset($this->storage->$name);
    }
    function __unset($name) {
        echo "Unsetting $name";
        unset($this->storage->$name);
    }
    static function create_sessions($sessions) {
        $result = array();
        foreach ($sessions as $session) {
            $result[] = new Session($session->username,
                                    $session->token,
                                    $session->storage,
                                    $session->browser,
                                    $session->start);
        }
        return $result;
    }
    static function cast($stdClass) {
        $storage = $stdClass->storage ? $stdClass->storage : new stdClass();
        return new Session($stdClass->username,
                           $stdClass->token,
                           $storage,
                           $stdClass->browser,
                           $stdClass->start);
    }
    static function new_session($username) {
        return new Session($username, token());
    }
}

And some test code:

$session = new Session('joe', '1234');
$session->mysql = 1234;
var_dump($session->mysql);
unset($session->mysql);
var_dump($session->mysql);

This is code of the added method:

function __unset($name) {
    echo "Unsetting $name";
    unset($this->storage->$name);
}

Check out the documentation to about the magic __unset method you need to add to your class:

http://php.net/manual/en/language.oop5.overloading.php#object.unset

__unset() is invoked when unset() is used on inaccessible properties.

Upvotes: 6

Related Questions