jablonka.czprosek.czf

freenet-router

Subversion Repositories:
[/] [trunk/] [freenet-router/] [var/] [www/] [freenet-router/] [Framework/] [Core/] [ObjectMixin.php] - Rev 2

Compare with Previous - Blame - Download


<?php

namespace Phem\Core;

/**
 * Description of ObjectMixin
 *
 * @author Vejvis
 */
final class ObjectMixin
{

    /** @var array */
    private static $methods;

    /**
     * Returns property value.
     * @param  object
     * @param  string  property name
     * @return mixed   property value
     * @throws MemberAccessException if the property is not defined.
     */
    public static function & get($_this, $name)
    {
        $class = get_class($_this);

        if ($name === '')
        {
            throw new MemberAccessException("Cannot read a class '$class' property without name.");
        }

        if (!isset(self::$methods[$class]))
        {
            // get_class_methods returns ONLY PUBLIC methods of objects
            // but returns static methods too (nothing doing...)
            // and is much faster than reflection
            // (works good since 5.0.4)
            self::$methods[$class] = array_flip(get_class_methods($class));
        }

        // public method as closure getter
        if (isset(self::$methods[$class][$name]))
        {
            $val = function() use ($_this, $name)
                    {
                        return call_user_func_array(array($_this, $name), func_get_args());
                    };
            return $val;
        }

        // property getter support
        $name[0] = $name[0] & "\xDF"; // case-sensitive checking, capitalize first character
        $m = 'get' . $name;
        if (isset(self::$methods[$class][$m]))
        {
            // ampersands:
            // - uses &__get() because declaration should be forward compatible
            // - doesn't call &$_this->$m because user could bypass property setter by: $x = & $obj->property; $x = 'new value';
            $val = $_this->$m();
            return $val;
        }

        $m = 'is' . $name;
        if (isset(self::$methods[$class][$m]))
        {
            $val = $_this->$m();
            return $val;
        }

        $type = isset(self::$methods[$class]['set' . $name]) ? 'a write-only' : 'an undeclared';
        $name = func_get_arg(1);
        throw new MemberAccessException("Cannot read $type property $class::\$$name.");
    }

    /**
     * Sets value of a property.
     * @param  object
     * @param  string  property name
     * @param  mixed   property value
     * @return void
     * @throws MemberAccessException if the property is not defined or is read-only
     */
    public static function set($_this, $name, $value)
    {
        $class = get_class($_this);

        if ($name === '')
        {
            throw new MemberAccessException("Cannot write to a class '$class' property without name.");
        }

        if (!isset(self::$methods[$class]))
        {
            self::$methods[$class] = array_flip(get_class_methods($class));
        }

        // property setter support
        $name[0] = $name[0] & "\xDF"; // case-sensitive checking, capitalize first character

        $m = 'set' . $name;
        if (isset(self::$methods[$class][$m]))
        {
            $_this->$m($value);
            return;
        }

        $type = isset(self::$methods[$class]['get' . $name]) || isset(self::$methods[$class]['is' . $name]) ? 'a read-only' : 'an undeclared';
        $name = func_get_arg(1);
        throw new MemberAccessException("Cannot write to $type property $class::\$$name.");
    }

}

Powered by WebSVN 2.2.1