【问题标题】:Using PHP Slim Framework inside of Classes在类中使用 PHP Slim 框架
【发布时间】:2012-03-15 17:50:52
【问题描述】:

我似乎无法让 Slim 框架访问 PHP 类范围内的函数:

<?php

class Controller {
    private $app;

    public function __construct() {
        $this->app = new Slim();

        $this->app->get('/', $this->home);

        $this->app->run();
    }

    public function home() {
        echo 'hi';
    }
}

这会导致以下错误:

致命错误:带有消息的未捕获异常“ErrorException” '未定义的属性:Controller::$home' 在 /Users/Oliver/Dropbox/Sites/grapevine/application/controller.php:9 堆栈跟踪:#0 /Users/Oliver/Dropbox/Sites/grapevine/application/controller.php(9): Slim::handleErrors(8, '未定义属性...', '/Users/Oliver/D...', 9, 数组)#1 /Users/Oliver/Dropbox/Sites/grapevine/public/index.php(14): Controller->__construct() #2 {main} 抛出 /Users/Oliver/Dropbox/Sites/grapevine/application/controller.php on 第 9 行

我尝试过这样做:

$this->app->get('/', $this->home());

但随后路由被忽略,每个页面都显示'hi',而不仅仅是'/'。

【问题讨论】:

  • 至少on the Slim site's demo,传递的是一个“匿名”函数。我不确定您是否可以通过这种方式传递对类方法的引用。
  • 请注意,要使用匿名函数,您至少需要version 5.3.0
  • 根据文档,您可以传递非匿名函数。它向后兼容 5.2。我的问题是:静态有什么大惊小怪的?为什么抱怨它?我不太熟悉使用静态的目的。我会仔细阅读问题档案以获取更多信息,但与此同时,如果有人对为什么 slim 抱怨静态成员函数有任何见解,我将不胜感激。
  • 与问题无关,但查看错误消息,我有一个好主意:在处理个人项目时在您的保管箱中输入代码,不要担心签入代码!谢谢!

标签: php frameworks slim


【解决方案1】:

对成员函数使用回调语法:

$this->app->get('/', array($this, 'home'));

【讨论】:

    【解决方案2】:

    以下应该可以工作(不过,可能需要将您的主页功能更改为静态!):

    $this->app->get('/', "Controller::home");
    

    【讨论】:

    • 谢谢。现在我收到这个错误:消息:call_user_func_array() 期望参数 1 是一个有效的回调,非静态方法 Controller::home() 不应该被静态调用。静态是什么意思?
    • 我确实必须将其更改为静态,但我希望能够访问该类及其属性,如下所示:hastebin.com/wesukifufu.coffee。但是,然后我收到以下错误:致命错误:在第 16 行的 /Users/Oliver/Dropbox/Sites/grapevine/application/controller.php 中不在对象上下文中时使用 $this
    • 您不能在静态上下文中使用$this。请改用Controller::$test。编辑:我差点忘了,当然你也得把 $test 设为静态。
    【解决方案3】:

    我有 this solution 从 Slim 内部容器注入构造函数

    基本上主要的魔法隐藏在__call函数中

    class App extends Slim
     public function __call($name, $params) {
      return function () use ($name, $params) {
      list($class, $action) = explode('_', $name . '_handle'); // default method is handle
    
      $args = [];
      $class = new \ReflectionClass($class);
      $constructor = $class->getConstructor();
      foreach ($constructor->getParameters() as $param) {
       $args[] = ($param->name === 'app') ? $this : $this->container->get($param->name);
      }
      $controller = $class->newInstanceArgs($args);
      return call_user_func([$controller, $action], func_get_args() + $params);
      };
     }
    }
    

    控制器需要在构造函数参数中有App:

    class Homepage {
    
     public $app;
    
     public function __construct(\App $app) {
      $this->app = $app;
     }
    }
    

    而index.php只有路由器设置

    $app = new \App();
    $app->get('/', $app->Homepage());
    $app->run(
    

    在此处查看完整代码https://gist.github.com/OzzyCzech/7230064

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-12-12
      • 2018-11-22
      • 2019-04-09
      • 1970-01-01
      • 2011-10-12
      • 2017-07-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多