PHP类:定义默认返回对象

I have a PHP Class with a Constructor and some Methods. Every Method need to have the same return stdClass Object. Only a few properties in each functoin of the stdClass Object should be diffrent from the default one(like the property value or status). How would you do that? I mean, i can define in every function an stdClass Object with all properties, but as I said, I only need to change a few properties in each function for the return.

Examplecode which doesn't work:

<?
    class Person{
        public $sName;
        public $oReturn = new stdClass();
        $oReturn->status = 200;
        $oReturn->value = "Personname";

        function __construct($sName) {
            $this->sName = $sName;
        }

        public function something($oData){
            //Declaration
            $this->oReturn->value = $oData->newName;
            //Main

            //Return
            return $this->oReturn;
        }
    }
?>

You can't declare properties like this:-

public $oReturn = new stdClass();

That is illegal in PHP. Do it like this:-

class Person{
    public $sName;
    public $oReturn;

    function __construct($sName) {
        $this->sName = $sName;
        $this->oReturn = new stdClass;
        $this->oReturn->status = 200;
        $this->oReturn->value = "Personname";
    }

    public function something($oData){
        //Declaration
        $this->oReturn->value = $oData->newName;
        //Main

        //Return
        return $this->oReturn;
    }
}

Now you can set whatever properties you want in $this->oReturn which, I think, is what you want to achieve.

See it working

You could just return a shared method that formats the data for you.

<?php
class Foo
{
    protected
        $defaults = array(
            'a' => 1,
            'b' => 2,
        );

    protected function reply(array $params = null) {
        $properties = $this->defaults;

        if ($params) {
            $properties = array_merge($properties, $params);
        }

        return (object) $properties;
    }

    public function a($a) {
        return $this->reply(array('a' => $a));
    }

    public function b($b) {
        return $this->reply(array('b' => $b));
    }
}

$foo = new Foo;
var_dump($foo->a('a'));
var_dump($foo->b('b'));

/*
    object(stdClass)#2 (2) {
      ["a"]=>
      string(1) "a"
      ["b"]=>
      int(2)
    }

    object(stdClass)#2 (2) {
      ["a"]=>
      int(1)
      ["b"]=>
      string(1) "b"
    }
*/

I think you might be after method chaining. You can create a class whose methods return $this, and then you can change your method calls.

Consider a class like the following:

<?php
class User
{
    protected $id;
    protected $name;
    protected $email;

    public function setName($name)
    {
        $this->name = $name;
        return $this;
    }

    public function setEmail($email)
    {
        $this->email = $email;
        return $this;
    }
}

You can then use it as follows:

<?php
$user = new User();
$user->setName('Martin')->setEmail('martin@example.com');

After this, your User class’s properties will reflect what values you’ve assigned to them in your chained method calls.

You can assign non-scalar values to class properties after class instantiation(AKA after new). See that the $oReturn value assignment is moved into the constructor.

class Person{
    public $sName;
    public $oReturn;
    protected $default_status = 200;
    protected $default_value = "Personname";

    function __construct($sName) {
        $this->sName = $sName;
        $this->oReturn = new stdClass();
        $this->oReturn->status = $this->default_status;
        $this->oReturn->value = $this->default_value;
    }

    public function something($oData){
        //Declaration
        $this->oReturn->value = $oData->newName;
        //Main

        //Return
        return $this->oReturn;
    }
}

Now, you can extend this class, to make small variations.

class PersonNotFound extends Person {
    protected $default_status = 404;
    protected $default_value = 'NotFound';
}

Let's see their results:

$oData = new stdClass();
$oData->newName = 'Neo';

$person_a = new Person("Triniti");
var_dump( $person_a->something($oData) );
// status = 200

$person_b => new PersonNotFound("Cyon");
var_dump( $person_b->something($oData) );
// status = 404

EDIT:

Constructor injection version:

class Person{
    public $sName;
    public $oReturn;

    function __construct($sName, $status = 200, $value = "Personname") {
        $this->sName = $sName;
        $this->oReturn = new stdClass();
        $this->oReturn->status = $status;
        $this->oReturn->value = $value;
    }

    public function something($oData){
        $this->oReturn->value = $oData->newName;
        return $this->oReturn;
    }
}

$person_a = new Person("Neo"); // 200, Personname as default
$person_b = new Person("Triniti", 404, "NotFound");