从另一个类调用非对象上的成员函数


Call to a member function on a non-object from another class

我正在学习 oop 并尝试在此过程中实现 php 标准 PSR-0 和 PSR-1。我首先创建了一个基于 Swiftlet 的小型 MVC 框架。

正在尝试从我从 url 调用的控制器中的基本视图控制器调用函数,并且我得到"在非对象上调用成员函数集()"。

所有类加载正常。所以在我的控制器中,我调用$this->view->set('helloWorld', 'Hello world!');但我收到一个错误。我在尝试正确构建命名空间结构时遇到了一些麻烦,所以也许这就是原因?

以下是文件结构:

索引.php

库/引导程序.php

库/视图.php

库/控制器.php

应用/控制器/索引.php

这是每个代码:

索引.php

<?php
namespace MVC;
    // Bootstrap the application
    require 'lib/Bootstrap.php';
    $app = new lib'Bootstrap;
    spl_autoload_register(array($app, 'autoload'));
    $app->run();
    $app->serve();

引导程序.php

namespace MVC'lib;
class Bootstrap 
{
    protected
        $action     = 'index',
        $controller,
        $hooks      = array(),
        $view
        ;
    /**
     * Run the application
     */
    function run() 
    {
               ... Code that gets controller and the action form the url
        $this->view = new 'lib'View($this, strtolower($controllerName));
        // Instantiate the controller
        $controllerName = 'app'Controllers''' . basename($controllerName);
        $this->controller = new $controllerName();                      
        // Call the controller action
        $this->registerHook('actionBefore');
        if ( method_exists($this->controller, $this->action) ) {
            $method = new 'ReflectionMethod($this->controller, $this->action);
            if ( $method->isPublic() && !$method->isFinal() && !$method->isConstructor() ) {
                $this->controller->{$this->action}();
            } else {
                $this->controller->notImplemented();
            }
        } else {
            $this->controller->notImplemented();
        }
        return array($this->view, $this->controller);
    }

<?php
namespace MVC'lib;
class Bootstrap 
{
    protected
        $action     = 'index',
        $args       = array(),
        $config     = array(),
        $controller,
        $hooks      = array(),
        $plugins    = array(),
        $rootPath   = '/',
        $singletons = array(),
        $view
        ;
    /**
     * Run the application
     */
    function run() 
    {
        // Determine the client-side path to root
        if ( !empty($_SERVER['REQUEST_URI']) ) {
            $this->rootPath = preg_replace('/(index'.php)?('?.*)?$/', '', $_SERVER['REQUEST_URI']);
            if ( !empty($_GET['route']) ) {
                $this->rootPath = preg_replace('/' . preg_quote($_GET['route'], '/') . '$/', '', $this->rootPath);
            }
        }
        // Extract controller name, view name, action name and arguments from URL
        $controllerName = 'Index';
        if ( !empty($_GET['route']) ) {
            $this->args = explode('/', $_GET['route']);
            if ( $this->args ) {
                $controllerName = str_replace(' ', '/', ucwords(str_replace('_', ' ', str_replace('-', '', array_shift($this->args)))));
            }
            if ( $action = $this->args ? array_shift($this->args) : '' ) {
                $this->action = str_replace('-', '', $action);
            }
        }
        if ( !is_file('app/Controllers/'. $controllerName . '.php') ) {
            $controllerName = 'Error404';
        }
        $this->view = new 'lib'View($this, strtolower($controllerName));
        // Instantiate the controller
        $controllerName = 'app'Controllers''' . basename($controllerName);
        $this->controller = new $controllerName();                      
        // Call the controller action
        $this->registerHook('actionBefore');
        if ( method_exists($this->controller, $this->action) ) {
            $method = new 'ReflectionMethod($this->controller, $this->action);
            if ( $method->isPublic() && !$method->isFinal() && !$method->isConstructor() ) {
                $this->controller->{$this->action}();
            } else {
                $this->controller->notImplemented();
            }
        } else {
            $this->controller->notImplemented();
        }
        $this->registerHook('actionAfter');
        return array($this->view, $this->controller);
    }
<?php
namespace MVC'lib;
class Bootstrap 
{
    protected
        $action     = 'index',
        $args       = array(),
        $config     = array(),
        $controller,
        $hooks      = array(),
        $plugins    = array(),
        $rootPath   = '/',
        $singletons = array(),
        $view
        ;
    /**
     * Run the application
     */
    function run() 
    {
        // Determine the client-side path to root
        if ( !empty($_SERVER['REQUEST_URI']) ) {
            $this->rootPath = preg_replace('/(index'.php)?('?.*)?$/', '', $_SERVER['REQUEST_URI']);
            if ( !empty($_GET['route']) ) {
                $this->rootPath = preg_replace('/' . preg_quote($_GET['route'], '/') . '$/', '', $this->rootPath);
            }
        }
        // Extract controller name, view name, action name and arguments from URL
        $controllerName = 'Index';
        if ( !empty($_GET['route']) ) {
            $this->args = explode('/', $_GET['route']);
            if ( $this->args ) {
                $controllerName = str_replace(' ', '/', ucwords(str_replace('_', ' ', str_replace('-', '', array_shift($this->args)))));
            }
            if ( $action = $this->args ? array_shift($this->args) : '' ) {
                $this->action = str_replace('-', '', $action);
            }
        }
        if ( !is_file('app/Controllers/'. $controllerName . '.php') ) {
            $controllerName = 'Error404';
        }
        $this->view = new 'lib'View($this, strtolower($controllerName));
        // Instantiate the controller
        $controllerName = 'app'Controllers''' . basename($controllerName);
        $this->controller = new $controllerName();                      
        // Call the controller action
        $this->registerHook('actionBefore');
        if ( method_exists($this->controller, $this->action) ) {
            $method = new 'ReflectionMethod($this->controller, $this->action);
            if ( $method->isPublic() && !$method->isFinal() && !$method->isConstructor() ) {
                $this->controller->{$this->action}();
            } else {
                $this->controller->notImplemented();
            }
        } else {
            $this->controller->notImplemented();
        }
        $this->registerHook('actionAfter');
        return array($this->view, $this->controller);
    }

库/视图.php

namespace lib;
class View 
{
    protected
        $app,
        $variables = array()
        ;
    public
        $name
        ;
    /**
     * Constructor
     * @param object $app
     * @param string $name
     */
    public function __construct($app, $name)
    {
        $this->app  = $app;
        $this->name = $name;
    }

    /**
     * Set a view variable
     * @param string $variable
     * @param mixed $value
     */
    public function set($variable, $value = null)
    {
        $this->variables[$variable] = $value;
    }

最后是应用程序/控制器/索引.php

namespace app'Controllers;
class index extends 'lib'Controller
{
    public function test()
    {
           // This gets the error
                   $this->view->set('helloWorld', 'Hello world!');  
    }
}

如果这是控制器中的所有代码,则$this->view不是对象。
尝试运行以下代码:

namespace app'Controllers;
class index extends 'lib'Controller
{
    public function test()
    {
           var_dump( $this->view );
           exit;
           $this->view->set('helloWorld', 'Hello world!');  
    }
}

您还应该知道,在 PHP 中,__construct() 方法不是继承的。
我一定受了脑残。

哦..我不明白,为什么这个问题有mvc标签。当您尝试编写类似 MVC 的东西时,问题本身与作为架构模式的 MVC 无关。