【问题标题】:PHP Overloading [closed]PHP重载[关闭]
【发布时间】:2012-11-26 23:16:08
【问题描述】:

我已经创建了自己的框架来开发我的个人作品集网站。我将它(非常)松散地基于我相当熟悉的 Zend Framework。除了在控制器中设置变量之外,我已经设法让事情正常工作,然后可以在 .phtml 文件中使用这些变量。这就是我目前所拥有的(例如,这里的 url 是 www.mydomain.com/services/hosting):

front.php

class front {
    private $sControllerName = 'home';
    private $sActionName = 'index';

    function __construct() {
        $this->view = new viewProperties();
        $aUriParts = $this->getUriParts();
        if (!empty($aUriParts[0])) {
            $this->sControllerName = $aUriParts[0];   
        }
        if (!empty($aUriParts[1])) {
            $this->sActionName = $aUriParts[1];   
        }
        $this->constructController();
        include('path/to/views/view.phtml');
    }

    private function constructController() {
        $sContFile = 'controllers/'.$this->sControllerName.'.php';
        if (@include($sContFile)) {
            $c = new $this->sControllerName();
            // Action method, if exists
            $this->doAction($c);
        }
    }

    public function getElement($name) {
        include('public_html/elements/'.$name);
    }

    public function renderContent() {
        $sViewFile = 'path/to/views/'.$this->sControllerName;
        if ($this->sActionName) {
            $sViewFile .= '/'.$this->sActionName.'.phtml';
        } else {
            $sViewFile .= '.php';
        }
        if (!@include($sViewFile)) {
            $this->render404();
        }
    }

    private function doAction($c) {
        $sActionFunc = str_replace('-', '_', $this->sActionName.'Action');
        if (method_exists($c,$sActionFunc)) {
            $c->$sActionFunc();
        }
    }

    private function render404() {
        include('path/to/views/404.phtml');
    }

    private function getUriParts() {
        $sUri = $_SERVER['REQUEST_URI'];
        $sUri = trim($sUri, "/");
        $sUri = str_replace("-", "_", $sUri);
        $aUriParts = explode("/", $sUri);
        return $aUriParts;
    }
}

viewProperties.php

class viewProperties {
    static $_instance = null;
    private $data = array();

    public static function getInstance() {
        if (null === self::$_instance) {
            self::$_instance = new self();
        }

        return self::$_instance;
    }

    public function __set($name, $value) {
        echo "Setting '$name' to '$value'\n";
        $this->data[$name] = $value;
    }

    public function __get($name) {
        echo "Getting '$name'\n";
        if (array_key_exists($name, $this->data)) {
            return $this->data[$name];
        }
    }

    public function __isset($name) {
        echo "Is '$name' set?\n";
        return isset($this->data[$name]);
    }

    public function __unset($name) {
        echo "Unsetting '$name'\n";
        unset($this->data[$name]);
    }
}

services.php

class services extends controller {
    public function indexAction() {
        $this->view->banner->src = '/path/to/images/banners/home_02.jpg';
        $this->view->banner->alt = 'banner title';
    }

    public function hostingAction() {
        $this->view->banner->src = '/path/to/images/banners/home_02.jpg';
        $this->view->banner->alt = 'banner title';
    }
}

在 hosting.phtml 我有:

<img src="<?php echo $this->view->banner->src ?>" alt="<?php echo $this->view->banner->title ?>" />

如何在控制器中设置属性(不仅仅是横幅),然后在视图中检索它们?非常感谢帮助/指导。

【问题讨论】:

  • 到底是什么问题?
  • 抱歉含糊不清。如何在控制器中设置属性(不仅仅是横幅),然后在视图中检索它们?

标签: php overloading


【解决方案1】:

由于您没有具体说明您遇到了什么问题,我将不得不从代码中猜测。

我猜您目前无法设置/检索横幅属性?

如果是这样,试试这个:

class services extends controller {
    public function indexAction() {
        $this->view->banner = array
        (
            'src' => '/path/to/images/banners/home_02.jpg',
            'alt' => 'banner title'
         );
    }

    public function hostingAction() {
        $this->view->banner = array
        (
            'src' => '/path/to/images/banners/home_02.jpg',
            'alt' => 'banner title'
        );
    }
}

<img src="<?php echo $this->view->banner['src'] ?>" alt="<?php echo $this->view->banner['title'] ?>" />

这是实现工作模型的简单修复,但并不完全符合您的目标。

要创建一个允许您通过“->”访问多个级别的动态变量,您可能需要创建一个 ViewElement 类型来包装结果赋值并提供 _* 方法。

在您的示例中,banner 在通过_get() 检索之前实际上并未创建(即从未调用过_set()) - 因此您的代码需要在调用_get() 时自动创建一个值一个不存在的值。

我还建议您的 ViewProperties 扩展 ViewElement 以减少重复代码。

这是我创造的东西(魔法在 __get() 中):

class viewProperties extends ViewElement {
    static $_instance = null;
    private $data = array ();
    public static function getInstance() {
        if (null === self::$_instance) {
            self::$_instance = new self ();
        }

        return self::$_instance;
    }
}
class ViewElement {
    private $data = array ();
    public function __set($name, $value) {
        echo "Setting '$name' to '$value'\n";
        $this->data [$name] = $value;
    }
    public function __get($name) {
        echo "Getting '$name'\n";
        if (! array_key_exists ( $name, $this->data )) {
            $this->data [$name] = new ViewElement();
        }
        return $this->data [$name];
    }
    public function __isset($name) {
        echo "Is '$name' set?\n";
        return isset ( $this->data [$name] );
    }
    public function __unset($name) {
        echo "Unsetting '$name'\n";
        unset ( $this->data [$name] );
    }
}

$view = viewProperties::getInstance();
$view->boo = "hoo";
$view->foo->bar = "baz";
print ("boo = '{$view->boo}', foo->bar='{$view->foo->bar}'");

[edit] 胖手指并在完成之前提交。

[编辑] 用可能的解决方案扩展答案。

【讨论】:

  • 非常感谢@David Farrel!我现在可以设置属性了。但是如何在 view.phtml 中访问这些内容?
  • view.phtl 有 doctype 和 标签,我希望能够从控制器操作中自定义这些标签。我尝试将$view = viewProperties::getInstance(); 放在front.php 中,但我什么也没得到。
  • 我需要了解更多关于您如何包含 .phtml 文件的信息,但是我看到您在问题中提供的文件有 $this-&gt;view-&gt;...,除非您正在执行此 .phtml在类文件中,$this 没有任何意义。如果它只是正常执行,则在文件顶部添加 &lt;?php $view = viewProperties::getInstance() ?&gt; 以将 $view 带入范围(如果 $view 是全局变量,则不添加),并将 $this-&gt;view-&gt;... 替换为 $view-&gt;... 可能会把戏。
  • 查看我最初发布的代码中的 front.php。 view.phtml 包含在 front.php 中的 __construct 函数中。在 view.phtml 中,我调用了“renderContent”函数,其中包含页面的特定内容。
  • 我建议让你的实例变量显式化——你似乎想要frontcontroller 类的$view。我会在这两个类中添加“private $view”。另外,我没有看到任何将 $view 传递给控制器​​实例的代码?您可能需要 setView($view) 方法或将 $view 作为参数的构造函数。此外,您没有使用我提供的额外 ViewElement 类更新您的原始帖子(如果它已关闭,您可以更新它吗?)但除非您这样做,否则您无法拥有设置 view-&gt;banner-&gt;src 的魔力而没有以前的横幅已定义。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-22
  • 2014-03-13
  • 1970-01-01
相关资源
最近更新 更多