【问题标题】:How to implement php function in slim 3如何在 slim 3 中实现 php 功能
【发布时间】:2018-01-21 21:49:49
【问题描述】:

我刚刚学习了 slim 3,我想将我的 slim 2 项目转换为 slim 3,但卡在了 PHP 函数中,尤其是带有参数。我不知道如何创建带参数的函数以及如何传递它。

例如,我有一个重要的功能来获取我的用户详细信息,我不知道如何转换为 Slim 3。

谢谢

function internalUserDetails($input) {
    
    try {
        $db = getDB(); //when convert to slim 3, I declared the DB in dependencies so I have to call the DB with '$this->db'
        $sql = "SELECT user_id, name, email, username FROM users WHERE username=:input or email=:input";
        $stmt = $db->prepare($sql);
        $stmt->bindParam("input", $input,PDO::PARAM_STR);
        $stmt->execute();
        $usernameDetails = $stmt->fetch(PDO::FETCH_OBJ);
        $usernameDetails->token = apiToken($usernameDetails->user_id);
        $db = null;
        return $usernameDetails;
        
    } catch(PDOException $e) {
        echo '{"error":{"text":'. $e->getMessage() .'}}';
    }
    
}

这是数据库依赖代码

$container['db'] = function ($c) {
    $db = $c['settings']['db'];
    $pdo = new PDO('mysql:host=' . $db['host'] . ';dbname=' . $db['dbname'],
        $db['user'], $db['pass']);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
    return $pdo;
};

运行时出现错误

不在对象上下文中使用 $this

【问题讨论】:

  • 当我使用 $this '不在对象上下文中使用 $this'
  • 我在上面的代码中没有看到任何$this
  • 在 slim 3 中,我的 getDB() 函数将被放入“依赖项”中,我应该使用 $this->db; 调用
  • 请添加您遇到问题并显示错误消息的代码。
  • 我已经添加了 slim 3 依赖项

标签: php rest api slim slim-3


【解决方案1】:

在 Slim 3 中,您应该使用容器来获取数据库实例。

在 config/settings.php 文件中插入并调整必要的连接设置

// Database settings
$config['db']['host'] = '127.0.0.1';
$config['db']['username'] = 'root';
$config['db']['password'] = '';
$config['db']['database'] = 'test';
$config['db']['charset'] = 'utf8';
$config['db']['collation'] = 'utf8_unicode_ci';

为 PDO 连接添加一个容器条目

$container['db'] = function (Container $container) {
    $settings = $container->get('settings');
    $host = $settings['db']['host'];
    $dbname = $settings['db']['database'];
    $username = $settings['db']['username'];
    $password = $settings['db']['password'];
    $charset = $settings['db']['charset'];
    $collate = $settings['db']['collation'];
    $dsn = "mysql:host=$host;dbname=$dbname;charset=$charset";
    $options = [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_PERSISTENT => false,
        PDO::ATTR_EMULATE_PREPARES => false,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES $charset COLLATE $collate"
    ];

    return new PDO($dsn, $username, $password, $options);
};

然后将 PDO 实例注入您的控制器类并通过成员变量访问它。

protected $db;

public function __construct(Container $container)
{
    $this->db = $container->get('db');
}

public function internalUserDetails(Request $request, Response $response)
{
    $this->db ...
}

如果你使用路由回调,那么像这样访问 PDO 实例:

$app->get('/', function (Request $request, Response $response, array $args) {
    $db = $this->get('db');
    // do something

    return $response;
});

【讨论】:

    【解决方案2】:

    为你的数据库创建一个类:

    <?php
    
    class Database
    {
        /**
         * Database username
         *
         * @var string
         */
        protected $username;
    
        /**
         * Database password
         *
         * @var string
         */
        protected $password;
    
        /**
         * Database host
         *
         * @var string
         */
        protected $host;
    
        /**
         * Database name
         *
         * @var string
         */
        protected $name;
    
        /**
         * Database constructor;
         */
        public function __construct()
        {
            try {
    
                // iniate $c... I'm not sure how you're getting the value..
                $c = [
                    'settings' => [
                        'db' => [
                            'host'   => '',
                            'dbname' => '',
                            'user'   => '',
                            'pass'   => '',
                        ],
                    ],
                ];
                $this->host     = $c['settings']['db']['host'];
                $this->name     = $c['settings']['db']['dbname'];
                $this->username = $c['settings']['db']['user'];
                $this->password = $c['settings']['db']['pass'];
    
                return $this->connect();
            }
        }
    
        /**
         * Connect to your database
         *
         * @return pdo
         */
        public function connect()
        {
            try{
                $pdo = new PDO('mysql:host=' . $this->host . ';dbname=' . $this->name,
                $this->username, $this->password);
    
                $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
                $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
    
                return $pdo;   
            } catch (Exception $ex){
                return $ex->getMessage();
            }
    
        }
    
    }
    

    在你的类中创建一个_construct 例如:

    /**
     * My Database
     *
     * @class 
     */
    protected $db;
    
    /**
     * Class constructor
     */
    public function __construct(Database $database){
        $this->db = $database;
    }
    

    然后您的$this-&gt;db 将被分配,因此您可以在您的方法中使用它

    【讨论】:

    • 您的数据库类会抛出 "Undefined variable $c"。您可能还应该将数据库连接绑定到容器。如果你在每个需要使用它的类中都使用new Database,它每次都会创建一个新的连接,这很糟糕。连接应该被重用。
    猜你喜欢
    • 1970-01-01
    • 2012-06-25
    • 1970-01-01
    • 2011-12-01
    • 2022-08-03
    • 2011-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多