2016-01-06 98 views
0

我想在一個對象上添加一個函數,該對象從該對象返回一個特定的值。動態添加方法到stdClass對象

我現在下面的代碼:

<?php 
namespace sdk; 
use core\Sdk; 

class Contents extends Sdk { 

    public $url; 
    public $id; 

    public function __call($method, $args) { 
     if (isset($this->$method)) { 
      $func = $this->$method; 
      return call_user_func_array($func, $args); 
     } 
    } 

    public function getContents($id = '') { 
     $request = 'contents/list/'.$id; 
     return $this->getRequest($request); 
    }//getContents 

    public function getContent($id) { 
     $request = 'contents/detail/'.$id; 
     $this->object = $this->getRequest($request); 
     $this->object->getItemAttribute = function($attribute) { 
      var_dump($this->object); 
     }; 
     return $this->object; 
    }//getContent 

}//Class Contents 

,我嘗試通過那朵代碼

$contents->getContent(1); 
$contents->object->getItemAttribute('titel'); 

啓動方法,但我不斷收到錯誤「未定義的方法」

什麼我做錯了嗎?

+0

您不能添加方法,一個stdClass的,但你可以創建一個匿名類,如果你正在運行php7 ....除了你的類不是一個stdClass –

+0

嗯,我不是:/是否有任何其他方式來獲得所需的結果? –

+0

難道你不能只使用一個神奇的'__get()'方法嗎? –

回答

1

PHP不是Javascript。您不能將方法添加到已經存在的類實例中(或者方法已經定義的類,就此而言)。

下面是一些另類的想法:

  1. 使用性能是功能(這是原則上你現在正在做什麼,只是用不同的調用)。

    $object->getItemAttribute = function($a) { 
        return $object->{$a}; 
    } 
    call_user_func($object->getItemAttribute); 
    

    我其實不建議實施此,因爲這將可能使你的代碼很難理解和惹怒了地獄,任何未來的維護(包括你自己)的。

  2. 定義一個實現新功能的包裝類:

    class RequestWithAdditionalAttribute { 
        private $wrapped; 
        public function __construct(\stdClass $wrapped) { 
         $this->wrapped = $wrapped; 
        } 
        public function getItemAttribute($a) { 
         return $this->wrapped->{$a}; 
        } 
    } 
    
    $wrappedObject = new RequestWithAdditionalAttribute($object) 
    
  3. PHP 7變種:創建一個匿名類:

    $wrappedObject = new class($object) { 
        private $wrapped; 
        public function __construct(\stdClass $wrapped) { 
         $this->wrapped = $wrapped; 
        } 
        public function getItemAttribute($a) { 
         return $this->wrapped->{$a}; 
        } 
    };