【问题标题】:Can't Access Parent Variable from Child Object无法从子对象访问父变量
【发布时间】:2016-12-27 00:31:06
【问题描述】:

我试图弄清楚为什么控制器类无法访问它扩展的父级的属性。

使用 $this 检索运输方式不会输出任何结果。 var_dump 表示它是一个字符串长度为 0 的数组。

使用 parent:: 返回错误“未定义的类常量 'shipinfo'”

知道我做错了什么吗?我认为扩展父类时可以访问公共/受保护的变量?

$data = trim(file_get_contents('php://input'));  
$link = new OrderLink($data);
$controller = new OrderLinkController();

class OrderLink{

protected $shipinfo = [
'name'      => '',
'address'   => '',
'unit'      => '',
'city'      => '',
'state'     => '',
'country'   => '',
'zip'       => '',
'phone'     => '',
'email'     => '',
'method'    => ''
];

protected $items;

function __construct($postdata)
{
    $xml = simplexml_load_string($postdata);

    $xml = $xml->Order;

    $billinfo = $xml->AddressInfo[1];
    $this->shipinfo['name']     =  strval($billinfo->Name->Full);
    $this->shipinfo['address']  =  strval($billinfo->Address1);
    $this->shipinfo['unit']     =  strval($billinfo->Address2);
    $this->shipinfo['city']     =  strval($billinfo->City);
    $this->shipinfo['state']    =  strval($billinfo->State);
    $this->shipinfo['country']  =  strval($billinfo->Country);
    $this->shipinfo['zip']      =  strval($billinfo->Zip);

  }
}

class OrderLinkController extends OrderLink
{

    function __construct(){

        echo 'Shipping Method: ' . $this->shipinfo['method'];
        echo parent::shipinfo['method'];

        if ($this->shipinfo['method']    == 'Local Pickup'){
            $this->shipinfo['method']    = 'Pickup';

        }
    }
}

【问题讨论】:

  • 您正在覆盖子类中的父类 __construct() 方法。
  • 那么如果我从子节点中移除构造函数,变量就可以访问了?
  • @Query - 不,你不需要删除构造函数,请看下面我的回答,我已经添加了一个进一步的注释来详细解释这个概念

标签: php oop


【解决方案1】:

几个小问题:

  • 您需要调用父构造函数,因此您应该将所需的 $postdata 通过子传递到父(或在子构造函数中创建)
  • 您可以使用 $this-> 获取船舶信息

    class OrderLinkController extends OrderLink
    {
    
        function __construct($postdata){
    
            parent::__construct($postdata);
    
            echo 'Shipping Method: ' . $this->shipinfo['method'];
            echo $this->shipinfo['method'];
    
            if ($this->shipinfo['method']    == 'Local Pickup'){
               $this->shipinfo['method']    = 'Pickup';
    
            }
        }
    }
    

进一步说明:您不需要像前几行那样同时实例化父级和子级:

$link = new OrderLink($data);
$controller = new OrderLinkController();

您应该只实例化子节点,通过子节点的构造函数发送数据,一旦子节点的构造函数与父节点的允许数据流动相匹配(请参阅我上面提供的代码以了解其工作原理):

$controller = new OrderLinkController($data);

【讨论】:

    【解决方案2】:

    我还要补充 Katie 的回答,除了代码本身的问题之外,还有类结构的问题。

    您拥有的类是 Web 应用程序的典型类,OrderLinkController 是一个负责处理传入请求的类 - 获取输入数据,对其进行验证并将执行传递给业务逻辑对象模型。

    在这种情况下,OrderLink 是模型,它与控制器之间不应存在父子关系。他们应该保持独立,我将从这样修改代码开始:

    // it may extend some BaseController class, but not the model class
    class OrderLinkController 
    {
    
        function run() {
            // get and parse the input data
            $data = trim(file_get_contents('php://input'));  
            $xml = simplexml_load_string($data);
            $xml = $xml->Order;
            // validate the data
            if ($xml->method == 'Local Pickup'){
                $xml->method = 'Pickup';
            }
            // pass the data to the model
            $model = new OrderLink($xml);
            // save the data or do something else with it
            $model->save(); 
    
            echo $model->getShippingInfo();
        }
    }
    
    
    class OrderLink{
    
        // it is usually better to have explicitly defined fields
        // rather than an array
        protected $name;
        protected $address;
        protected $unit;
        protected $city;
        protected $state;
        protected $country;
        protected $zip;
        protected $phone;
        protected $email;
        protected $items;
    
        // model gets already parsed data
        function __construct($data)
        {
            $billinfo = $data->AddressInfo[1];
            $this->shipinfo['name']     =  strval($billinfo->Name->Full);
            $this->shipinfo['address']  =  strval($billinfo->Address1);
            $this->shipinfo['unit']     =  strval($billinfo->Address2);
            $this->shipinfo['city']     =  strval($billinfo->City);
            $this->shipinfo['state']    =  strval($billinfo->State);
            $this->shipinfo['country']  =  strval($billinfo->Country);
            $this->shipinfo['zip']      =  strval($billinfo->Zip);
        }
    
        public function getShippingInfo() {
            return 'Shipping Method: ' . $this->method;
        }
    }
    
    // create and run the controller
    $controller = new OrderLinkController();
    $controller->run();
    

    【讨论】:

      猜你喜欢
      • 2020-12-03
      • 1970-01-01
      • 2013-04-28
      • 1970-01-01
      • 2021-09-28
      • 2016-03-04
      • 2023-04-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多