【问题标题】:PHP subclass can't access public variable set by parentPHP子类无法访问父类设置的公共变量
【发布时间】:2010-08-04 21:47:10
【问题描述】:

总的来说,我对 PHP 和 OOP 很陌生。我正在将 codeigniter 用于框架,目前正在尝试构建一个“BuildLinks”类,它将根据用户登陆的 URL 将用户重定向到正确的链接。

控制器将正确的变量传递给类,而函数 build_afflink() 根据 var1 选择接下来要调用的类

控制器:

    function out($var1, $var2)
{
    // redirect to link after parsing data
    $debug='1';
    $params = array('var1'=>$var1, 'var2'=>$var2);
    $this->load->library('BuildLinks', $params);
    if ($debug=='0'){
        $redirect = $this->buildlinks->build_afflink();
        redirect($redirect, 'location', 301);
    }
    else {
        var_dump($this->buildlinks->build_afflink());
    }

}

BuildLinks 类是一项正在进行的工作......但它被我需要支持的所有其他站点扩展。

BuildLinks 类:

    class BuildLinks
{
    public $var1;
    public $var2;
    public $link;
    function __construct($params)
    {
        //populate up inititial variables from $params array (passed from controller)
        $this->var1 = (string)$params['var1'];
        $this->var2 = (string)$params['var2'];
        echo __class__ . ' loaded....' . 'var1: '.$this->var1 . '    var2: ' .$this->var2. '<br/>';

    }
    public function get_var1()
    {
        return $this->var1;
    }

    public function set_var1($var1)
    {
        $this->var1 = $var1;
    }

    public function get_var2()
    {
        return $this->var2;
    }

    public function set_var2($var2)
    {
        $this->var2 = $var2;
    }


    function build_thelink()
    {
        switch ($this->var1) {
            case 'amazon':
                //echo 'Amazon is our vendor.<br>';
                $newobj = new Amazon;
// Amazon subclass returns the correct affiliate link

                return $newobj->affiliate_link();
                break;
            case 'ebay':
                $newobj = new Ebay;
         //ebay subclass however, cannot access the public var var1, it returns a null value for $this->var1
                return $newobj->affiliate_link();
                break;
        }

    }
}

基本上,当我创建一个新的 Ebay 对象时,它无法访问父类 BuildLinks 中的任何公共变量。我做错了什么?

在这个例子中,我让它构造初始变量并回显一些信息以进行调试。

编辑:如果我将 __construct 更改为:

    function __construct($params)
    {
        //populate up inititial variables from $params array (passed from controller)
        $this->var1 = (string)$params['var1'];
        $this->var2 = (string)$params['var2'];
        echo __class__ . ' loaded....' . 'var1: '.$this->var1. '    var2: ' .$this->var2 . '<br/>';
        var_dump(get_class_vars(get_class($this)));
}

然后我得到这个作为输出:

    BuildLinks loaded....var1: ebay var2: somedata

array
  'var1' => null
  'var2' => null
  'link' => null

以下工作正常:

$newobj = new Amazon;
return $newobj->affiliate_link();

这不是,但类几乎相同...

$newobj = new Ebay;
return $newobj->affiliate_link();

这里是 ebay 类:

  class Ebay extends BuildLinks
{
    private $res;
    //TODO: language/multiple site support
    //public $locale;
    function __construct()
    {
        //echo __class__ . ' loaded....' . 'vendor: '.$this->vendor . '    isbn: ' .$this->isbn . '<br/>';               
    }

    function add_to_cart_button($isbn, $locale)
    {
    }
    function affiliate_link()
    {
        $this->get_info();
        return $this->link;
    }
    // Load $this->api_call() and return Amazon SimpleXML response object, load variables
    function get_info()
    {
        $apicall = $this->api_call();
        //build variables
       foreach ($apicall->searchResult->item as $item) {
        $this->link = (string )$item->viewItemURL;
        }
    }

    // Generate API call and return simplexml object $res
    function api_call()
    {
        //build $apicall here
        $res = simplexml_load_file($apicall);

        // Check to see if the request was successful, else print an error
        if ($res->ack == "Success") {
            $this->res = $res;
            return $res;
        } else {
            echo 'api_call() unsuccessful';
        }
    }
}

【问题讨论】:

  • 你还没有展示 Ebay 类的定义——它肯定扩展了 BuildLinks 吗?
  • 另外,父类 BuildLinks 似乎没有affiliate_link() 方法...?
  • 是的,Ebay 类扩展了 BuildLinks。你是对的,它没有affiliate_link() 方法。我调用 build_thelink() 从子类返回链接。我已经编辑了我的帖子以包含我的 ebay 子类

标签: php oop scope subclass


【解决方案1】:

ebay 课程的这一部分对我来说没有太大意义:

function api_call()
    {
        //build $apicall here
        $res = simplexml_load_file($apicall);

        // Check to see if the request was successful, else print an error
        if ($res->ack == "Success") {
            $this->res = $res;
            return $res;
        } else {
            echo 'api_call() unsuccessful';
        }
    }

simplexml_load_file($apicall); 没有加载任何东西。 $apicall 在哪里?如果你调试它,它是否会回显“api_call() unsuccessful”?

因为如果不成功,则不会设置 Ebay::link,因此 return $newobj-&gt;affiliate_link(); 不会最终返回任何内容。

为澄清起见,$apicall 应在调用simplexml_load_file($apicall); 之前设置为文件路径

【讨论】:

  • 这里我没有包含整个函数——在我的函数中,$apicall 变量是在 simplexml_load_file($apicall); 之前构造的。叫做。 api 调用工作得很好,但我必须在我希望 $this->var2 所在的字符串中硬编码。这就是这里的问题——子类 Ebay 不能引用父类设置的任何变量
  • 看看 Mchl 的构造函数建议。另外,我注意到,有时如果你明确地公开一个成员/方法,它也会隐式地使其成为静态的。任何可以使用 $BuildLinks::var2 访问它们的机会(不过,这有点疯狂......)。
  • 感谢您的建议,但我还没有解决问题:/
【解决方案2】:

Ebay::get_info() 这样做

foreach ($apicall->searchResult->item as $item) {
  $this->link = (string )$item->viewItemURL;
}

如果$apicall-&gt;searchResult-&gt;item 碰巧有几个元素,其中最后一个是空的,您将只得到最后一个空元素。

不过,这是一个疯狂的猜测。

[添加]

您正在重写 Ebay 中的构造函数,因此如果您希望调用 BuildLinks 的类构造函数,则需要显式执行此操作。

【讨论】:

  • 当 BuildLinks::build_thelink() 加载 ebay 类时,我设置 Ebay 的构造函数来回显 $this->var1 和 $this->var2。这两个都是空的——所以在它到达 Ebay::get_info() 之前它就是一个问题
  • 你的构造函数调用父类的构造函数吗?
  • 如果将构造函数设置为调用 parent::__construct();,则我从控制器传递给父级的 $params 数组不可用于引用。奇怪的是,Amazon 类出于某种原因能够访问 var1 和 var2。这在 Amazon::api_call() 中运行良好 -- $res = $pas->item_search('$this->var2', array('ResponseGroup' => 'Large'));
  • 哦,我明白你在说什么。如何将变量从 CI 控制器传递到我的类构造函数中,以便为每个子类构造/可用它们?
  • 可能会重新考虑您的类依赖关系。如果父类不能在与扩展类相同的上下文中使用,则违反en.wikipedia.org/wiki/Liskov_substitution_principle
猜你喜欢
  • 2023-04-01
  • 2012-04-16
  • 1970-01-01
  • 1970-01-01
  • 2020-02-13
  • 2019-12-04
  • 1970-01-01
  • 2023-03-27
  • 2010-12-31
相关资源
最近更新 更多