【问题标题】:PHP Slim 3 - Accessing class object instances within a slim routePHP Slim 3 - 在一条纤细的路由中访问类对象实例
【发布时间】:2018-10-08 13:36:19
【问题描述】:

因此,我正在学习如何编写 Slim 3 PHP 身份验证应用程序,并使用示例代码结构来帮助我入门。示例代码有一个名为 dependencies.php 的文件,该文件具有一系列创建其他类的对象实例的函数。然后将它们分配给具有每个函数名称的 $container 变量。在 dependencies.php 文件中可以看到这些函数的示例:

$container['view'] = function ($container) {
    $view = new \Slim\Views\Twig(
        $container['settings']['view']['template_path'],
        $container['settings']['view']['twig'],
        [
            'debug' => true // This line should enable debug mode
        ]
    );

    $basePath = rtrim(str_ireplace('index.php', '', $container['request']->getUri()->getBasePath()), '/');
    $view->addExtension(new Slim\Views\TwigExtension($container['router'], $basePath));

    $view->addExtension(new \Twig_Extension_Debug());

    return $view;
};

$container['validate_sanitize'] = function ($container)
{
    $class_path = $container->get('settings')['class_path'];
    require $class_path . 'ValidateSanitize.php';
    $validator = new ValidateSanitize();
    return $validator;
};

$container['hash_password'] = function($container)
{
    $class_path = $container->get('settings')['class_path'];
    require $class_path . 'HashPassword.php';
    $hash = new HashPassword();
    return $hash;
};

然后在我的苗条路线中以某种方式调用这些函数。例如在我的register.php slim 路由中,validate_sanitize 类对象是用一个简单的

$this->get(‘validate_sanitize’); 

并分配给一个变量,然后我可以使用它来调用validate_sanitize 类中的方法。

但是我不明白这个get 方法如何从dependencies.php 文件中调用一个类对象。

这是前面提到的注册路由,它是对传入表单数据的发布请求:

$app->post('/register', function(Request $request, Response $response)
{
    $arr_tainted_params = $request->getParsedBody();

    $sanitizer_validator = $this->get('validate_sanitize'); //here for example
    $password_hasher = $this->get('hash_password');

    $tainted_email = $arr_tainted_params['email'];
    $tainted_username = $arr_tainted_params['username'];
    $tainted_password = $arr_tainted_params['password'];

    $model = $this->get('model');
    $sql_wrapper = $this->get('sql_wrapper');
    $sql_queries = $this->get('sql_queries');
    $db_handle = $this->get('dbase');

    $cleaned_email = $sanitizer_validator->sanitize_input($tainted_email, FILTER_SANITIZE_EMAIL);
    $cleaned_username = $sanitizer_validator->sanitize_input($tainted_username, FILTER_SANITIZE_STRING);
    $cleaned_password = $sanitizer_validator->sanitize_input($tainted_password, FILTER_SANITIZE_STRING);
 });

我所有的路由都包含在一个如下所示的 routes.php 文件中:

 <?php

require 'routes/change_password.php';
require 'routes/forgot_password.php';
require 'routes/homepage.php';
require 'routes/login.php';
require 'routes/logout.php';
require 'routes/register.php';

还有一个引导文件,用于创建新的 Slim 容器、Slim App 实例,还包括必要的文件。我也不完全确定 Slim\Container 是什么或它的作用。此引导文件如下所示:

<?php

session_start();

require __DIR__ . '/../vendor/autoload.php';

$settings = require __DIR__ . '/app/settings.php'; //an array of options containing database configurations and the path to twig templates

$container = new \Slim\Container($settings); //not sure what this does

require __DIR__ . '/app/dependencies.php';

$app = new \Slim\App($container);

require __DIR__ . '/app/routes.php';

$app→run();

我尝试阅读大量文章以及观看各种 YouTube 视频,但他们使用控制器的方式不同,这只会增加我的复杂性和困惑。由于我发现代码结构相当简单,因此我更愿意对这个特定示例进行解释。

谢谢。

【问题讨论】:

    标签: php object routes instance slim-3


    【解决方案1】:

    内部路由可调用,$this 将指向$container 实例。

    在 Slim 3.0 中,如果您查看 Slim\App 类的 map() 方法,您将看到以下代码:

    if ($callable instanceof Closure) {
       $callable = $callable->bindTo($this->container);
    }
    

    bindTo() 使您可以使用$this 变量访问可调用路由内的容器。

    如果您想使用类作为路由处理程序并希望访问类内的容器实例,您需要手动传递它。例如

    <?php 
    namespace App\Controller;
    
    class MyPostRegisterController
    {
        private $container;
    
        public function __constructor($container)
        {
            $this->container = $container;
        }
    
        public function __invoke(Request $request, Response $response)
        {
            $sanitizer_validator = $this->container->get('validate_sanitize'); 
            //do something
        }
    }
    

    然后你可以定义路由如下

    $app->post('/register', App\Controller\MyPostRegisterController::class);
    

    如果 Slim 在依赖容器中找不到 MyPostController 类,它会尝试创建它们并传递容器实例。

    更新

    要调用其他方法,请在类名后附加方法名,用冒号分隔。例如,跟随route registration 将调用MyPostRegisterController 类中的home() 方法。

    $app->post('/register', App\Controller\MyPostRegisterController::class . ':home');
    

    【讨论】:

    • 抱歉,回复晚了,我现在更了解这是如何工作的,谢谢。这也与我听说过的一个叫做依赖注入的术语有关吗?我这样说是因为我有 dependencies.php。
    • $app->post('/register', App\Controller\MyPostRegisterController::class);工作正常,但如果我想调用 MyPostRegisterController 类的另一个方法
    • 只需附加 '':methodName',例如 $app-&gt;post('/register', App\Controller\MyPostRegisterController::class . ':home'); 将调用 home() 方法
    猜你喜欢
    • 2020-12-30
    • 1970-01-01
    • 2016-05-12
    • 1970-01-01
    • 1970-01-01
    • 2014-02-21
    • 2020-05-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多