在php中获取设置属性

时间:2012-02-16 22:50:31

标签: php get set

我来自C#环境,我开始在学校学习PHP。 我习惯用C#设置我的属性。

public int ID { get; set; }

在php中与此相同的是什么?

感谢。

7 个答案:

答案 0 :(得分:21)

虽然在将来的版本中有some proposals for implementing,但没有。 现在你不幸需要手工申报所有的getter和setter。

private $ID;

public function setID($ID) {
  $this->ID = $ID;
}

public function getID() {
  return $this->ID;
}

对于某些魔法(PHP喜欢魔法),你可以查找__set__get magic methods.

实施例

class MyClass {

  private $ID;

  private function setID($ID) {
    $this->ID = $ID;
  }

  private function getID() {
    return $this->ID;
  }


  public function __set($name,$value) {
    switch($name) { //this is kind of silly example, bt shows the idea
      case 'ID': 
        return $this->setID($value);
    }
  }

  public function __get($name) {
    switch($name) {
      case 'ID': 
        return $this->getID();
    }
  }

}


$object = new MyClass();
$object->ID = 'foo'; //setID('foo') will be called

答案 1 :(得分:6)

Mchi是正确的,但还有另一种方法是使用单一功能

    private $ID;

public function ID( $value = "" )

{

    if( empty( $value ) )

        return $this->ID;

    else

        $this->ID = $value;

}

但是,这种方法几乎与你在c#中所做的一致。但这只是另一种选择

或者尝试在课堂上使用php的__set和__get更多信息

http://php.net/manual/en/language.oop5.overloading.php

答案 2 :(得分:6)

感谢大家的回答。它帮助我创建了这样的东西:

在我的父类中:

public function __get($name){

    if (ObjectHelper::existsMethod($this,$name)){
        return $this->$name();
    }

    return null;
}

public function __set($name, $value){

    if (ObjectHelper::existsMethod($this,$name))
        $this->$name($value);
}

ObjectHelper :: existsMethod是一个只检查给定的受保护方法是否存在的方法。

private $_propertyName = null;

protected function PropertyName($value = ""){

    if (empty($value)) // getter
    {
        if ($this-> _propertyName != null)
            return $this->_propertyName;
    }
    else // setter
    {
        $this-> _propertyName = $value;
    }

    return null;
}

所以我可以在任何类中使用这样的东西:

$class = new Class();
$class->PropertyName = "test";
echo $class->PropertyName;

我受到了C#的启发:)

你怎么看待这个,伙计们?

如果有人想使用它,这是我的ObjectHelper:

namespace Helpers;

use ReflectionMethod;

class ObjectHelper {

public static function existsMethod($obj, $methodName){

    $methods = self::getMethods($obj);

    $neededObject = array_filter(
        $methods,
        function ($e) use($methodName) {
            return $e->Name == $methodName;
         }
    );

    if (is_array($neededObject))
        return true;

    return false;
}

public static function getMethods($obj){

    $var = new \ReflectionClass($obj);

    return $var->getMethods(ReflectionMethod::IS_PROTECTED);
}
}

答案 3 :(得分:3)

使用变量函数名称

的另一个示例
class MyClass {

  private $ID;
  protected $ID2;

  private function setID($ID) {
    $this->ID = $ID;
  }
  private function getID() {
    return $this->ID;
  }
  private function setID2($ID2) {
    $this->ID2 = $ID2;
  }

  private function getID2() {
    return $this->ID2;
  }
  public function __set($name,$value) {
    $functionname='set'.$name;
    return $this->$functionname($value);
  }
  public function __get($name) {
    $functionname='get'.$name;
    return $this->$functionname();
  }

}


$object = new MyClass();
$object->ID = 'foo'; //setID('foo') will be called
$object->ID2 = 'bar'; //setID2('bar') will be called

答案 4 :(得分:1)

private $ID;

public function getsetID($value = NULL)
{
    if ($value === NULL) {
        return $this->ID;
    } else {
        $this->ID = $value;
    }
}

答案 5 :(得分:0)

我知道我在这个问题上对派对来说有点迟了,但我自己也有同样的问题/想法。作为一名做PHP的C#开发人员,当工作需要时,我希望有一种简单的方法来创建属性,就像我能够在C#中一样。

我今天下午起草了一份初稿,它允许您创建支持字段并指定其访问者或具有没有支持字段的纯访问者。我将在代码发展时更新我的​​答案,并在我将其转换为可以作为composer包导入的状态时提供链接。

为简单起见,我将该功能创建为PHP特征,因此您可以将其放入所需的任何类,而不必扩展基类。最后,我希望扩展此功能,以区分对属性的外部公共调用和受保护/私有调用。

以下是特质本身的代码:     

trait PropertyAccessorTrait
{
    private static $__propertyAccessors = [];

    /* @property string $__propertyPrefix */

    public function __get($name)
    {
        $this->__populatePropertyAcessors($name);

        return $this->__performGet($name);
    }

    public function __set($name, $value)
    {
        $this->__populatePropertyAcessors($name);

        $this->__performSet($name, $value);
    }

    public function __isset($name)
    {
        // TODO: Implement __isset() method.
    }

    public function __unset($name)
    {
        // TODO: Implement __unset() method.
    }

    protected function __getBackingFieldName($name)
    {
        if (property_exists(self::class, '__propertyPrefix')) {
            $prefix = $this->__propertyPrefix;
        } else {
            $prefix = '';
        }

        return $prefix . $name;
    }

    protected function __canget($name)
    {
        $accessors = $this->__getPropertyAccessors($name);

        return $accessors !== null && isset($accessors['get']);
    }

    protected function __canset($name)
    {
        $accessors = $this->__getPropertyAccessors($name);

        return $accessors !== null && isset($accessors['set']);
    }

    protected function __performGet($name)
    {
        if (!$this->__canget($name)) {
            throw new \Exception('Getter not allowed for property: ' . $name);
        }

        $accessors = $this->__getPropertyAccessors($name)['get'];

        /* @var \ReflectionMethod $method */
        $method = $accessors['method'];

        if (!empty($method)) {
            return $method->invoke($this);
        }

        return $this->{$this->__getBackingFieldName($name)};
    }

    protected function __performSet($name, $value)
    {
        if (!$this->__canset($name)) {
            throw new \Exception('Setter not allowed for property: ' . $name);
        }

        $accessors = $this->__getPropertyAccessors($name)['set'];

        /* @var \ReflectionMethod $method */
        $method = $accessors['method'];

        if (!empty($method)) {
            return $method->invoke($this, $value);
        }

        $this->{$this->__getBackingFieldName($name)} = $value;
    }

    protected function __getPropertyAccessors($name)
    {
        return isset(self::$__propertyAccessors[$name])
            ? self::$__propertyAccessors[$name]
            : null
            ;
    }

    protected function __getAccessorsFromDocBlock($docblock)
    {
        $accessors = [];

        if (!empty(trim($docblock))) {
            $doclines = null;

            if (!empty($docblock)) {
                $doclines = explode("\n", $docblock);
            }

            if (!empty($doclines)) {
                foreach ($doclines as $line) {
                    if (preg_match('/@(get|set)\\s+(public|private|protected)/', $line, $matches)) {
                        $accessors[$matches[1]]['visibility'] = $matches[2];
                    }
                }
            }
        }

        return $accessors;
    }

    protected function __populatePropertyAcessors($name)
    {
        if ($this->__getPropertyAccessors($name) !== null) return;

        try {
            $property = new \ReflectionProperty(self::class, $this->__getBackingFieldName($name));
        } catch (\ReflectionException $ex) {
            $property = null;
        }

        $accessors = [];

        if ($property != null) {
            $accessors = $this->__getAccessorsFromDocBlock($property->getDocComment());
        }

        try {
            $methodName = 'get' . ucfirst($name);
            $method = new \ReflectionMethod(self::class, $methodName);
            $method->setAccessible(true);
            $accessors = array_merge($accessors, $this->__getAccessorsFromDocBlock($method->getDocComment()));
        } catch (\ReflectionException $ex) {
            $method = null;
        }


        if ($method !== null || isset($accessors['get'])) {
            $accessors['get']['method'] = $method;
        }

        try {
            $methodName = 'set' . ucfirst($name);
            $method = new \ReflectionMethod(self::class, $methodName);
            $method->setAccessible(true);
            $accessors = array_merge($accessors, $this->__getAccessorsFromDocBlock($method->getDocComment()));
        } catch (\ReflectionException $ex) {
            $method = null;
        }

        if ($method !== null || isset($accessors['set'])) {
            $accessors['set']['method'] = $method;
        }

        self::$__propertyAccessors[$name] = $accessors;
    }
}

这是我使用Codeception格式创建的快速单元测试:

<?php

class PropertyAssesorTraitTestClass
{
    use PropertyAccessorTrait;

    private $__propertyPrefix = '_';

    /**
     * @get public
     * @set public
     */
    private $_integer = 1;

    /**
     * @get public
     */
    private $_getonly = 100;

    /**
     * @set public
     */
    private $_setonly;

    private $_customDoubler;

    private function getCustomDoubler()
    {
        return $this->_customDoubler * 2;
    }

    private function setCustomDoubler($value)
    {
        $this->_customDoubler = $value * 2;
    }

    public $publicField = 1234;

    /**
     * @return int
     * @get public
     */
    private function getPureAccessor()
    {
        return $this->publicField;
    }

    /**
     * @param $value
     * @set public
     */
    private function setPureAccessor($value)
    {
        $this->publicField = $value;
    }

    private $_purePrivate = 256;
}

$I = new UnitTester($scenario);
$I->wantTo('Ensure properties are accessed correctly');

$instance = new PropertyAssesorTraitTestClass();
$I->assertSame(1, $instance->integer);

$instance->integer = 2;
$I->assertSame(2, $instance->integer);

$instance->integer = $instance->integer + 1;
$I->assertSame(3, $instance->integer);

$instance->integer++;
$I->assertSame(4, $instance->integer);

$I->assertSame(100, $instance->getonly);
$I->expectException('Exception', function () use ($instance) { $instance->getonly = 50; });

$instance->setonly = 50;
$I->expectException('Exception', function () use ($instance) { $a = $instance->setonly; });

$instance->customDoubler = 100;
$I->assertSame(400, $instance->customDoubler);

$I->assertSame(1234, $instance->publicField);
$instance->pureAccessor = 1000;
$I->assertSame(1000, $instance->publicField);
$instance->publicField = 1234;
$I->assertSame(1234, $instance->publicField);
$I->assertSame(1234, $instance->pureAccessor);

$I->expectException('Exception', function () use ($instance) { return $instance->purePrivate; });

答案 6 :(得分:-3)

这是PHP;你不需要设置

class MyClass {
  public $ID;
}

$object = new MyClass();
$object->ID = 'foo';
echo $object->ID;

将起作用