Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php Can';无法从子对象访问父变量_Php_Oop - Fatal编程技术网

Php Can';无法从子对象访问父变量

Php Can';无法从子对象访问父变量,php,oop,Php,Oop,我试图弄明白为什么控制器类无法访问它扩展的父类的属性 使用$this检索shipping方法不会输出任何内容。Var_dump表示它是一个字符串长度为0的数组 使用parent::返回错误“未定义的类常量'shipinfo'” 知道我做错了什么吗?我认为当父类被扩展时可以访问公共/受保护的变量 $data = trim(file_get_contents('php://input')); $link = new OrderLink($data); $controller = new Orde

我试图弄明白为什么控制器类无法访问它扩展的父类的属性

使用$this检索shipping方法不会输出任何内容。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';

        }
    }
}

有几个小问题:

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

    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();
只有在子构造函数与父构造函数匹配并允许数据流动时,才应该实例化子构造函数,并通过子构造函数发送数据(请参阅上面提供的代码了解其工作原理):


我还要补充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();

您正在覆盖子类中的父类_construct()方法。因此,如果我从子类中删除构造函数,则可以访问变量?@Query-否,您不需要删除构造函数,请参见下面的答案,我已添加了进一步的注释来详细解释此概念
// 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();