0

在类中包含和/或包装非类的好模式是什么?例如,我需要使用这个 php 文件https://github.com/widop/phpbb3/blob/master/common.php来登录我的 phpbb 板。具体来说,我需要这个文件来引导加载 phpbb,然后我将使用 $user 和 $auth 变量来登录用户。在我的代码中,我有一个 AuthClient 类。

我正在尝试找出最佳实践来包含来自 phpbb 的 common.php 并在我的班级中使用它:

=========根据反馈编辑=======================

我相信我已经取得了进步,但它仍然无法正常工作。
收到错误:

[2013-09-05 14:28:49] log.ERROR: exception 'Symfony\Component\Debug\Exception\FatalErrorException' with message 'Cannot redeclare class auth' in /var/www/phpbb3/includes/auth.php:24
Stack trace:
#0 [internal function]: Illuminate\Exception\Handler->handleShutdown()
#1 {main} [] []

这引用了 bootstrap.php 加载的非命名空间类

https://github.com/widop/phpbb3/blob/master/common.php
https://github.com/widop/phpbb3/blob/master/includes/auth.php

引导程序.php

define('IN_PHPBB', true);
$phpbb_root_path = base_path() . "/phpbb3/";
$phpEx = substr(strrchr(__FILE__, '.'), 1);
require_once(base_path() . '/phpbb3/common.php');

登录控制器.php - Laravel

use myproject\models\User;
use myproject\models\phpbb\Phpbb;
use myproject\models\phpbb\AuthClient;
use myproject\models\phpbb\User as PhpbbUser;

require_once(base_path() . '/app/models/Phpbb/bootstrap.php');

class LoginController extends BaseController{
public function login(){
    //...login in main application
    //Login in phpbb - more ewww
    global $user;
    global $auth;
    $phpbb = new AuthClient($user, $auth);
    $phpbb->login();
}
}

AuthClient.php

<?php
namespace myproject\models\phpbb;

use myproject\models\phpbb\Phpbb;

class AuthClient{

protected $user;
protected $auth;

public function  __construct($user, $auth){
    $this->user = $user;
    $this->auth = $auth;
}

public function login($user_id, $admin, $autologin){
    $this->user->session_begin();
    $this->auth->acl($this->user->data);
    $result = $this->user->session_create($user_id, $admin, $autologin, true);
}

public function logout(){
    $this->user->session_kill();
    $this->user->session_begin();
}
}

反馈之前的原始代码 - 不再使用**

class AuthClient implements IAuthClient{

protected $user;
protected $auth;

public function  __construct(){
    /** Bootloading PHPBB */
    define('IN_PHPBB', true);
    $phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './';
    $phpEx = substr(strrchr(__FILE__, '.'), 1);
    include($phpbb_root_path . 'common.' . $phpEx);

    // Start session management
    $this->user = $user;
    $this->auth = $auth;
    $this->user->session_begin();
    $this->auth->acl($user->data);

}

public function login($user_id, $admin, $autologin){
    $result = $this->user->session_create($user_id, $admin, $autologin, true);
}

public function logout(){
    $this->user->session_kill();
        $this->user->session_begin();
}
}
4

3 回答 3

0

将代码放入构造函数意味着以下内容:

  • 任何时候你创建new AuthClient() ;,你都将执行相同的代码,定义已经定义的常量等,这是一个非常糟糕的主意并触发错误。

  • 此外,方法可以是静态的,因此,如果不创建对象的实例,就不会执行代码。

通常最好将与类无关的代码移到外面,因为有时您不需要任何东西,只需要类功能。也更好,因为带有类的文件不需要多次包含,这样可以防止代码的重复执行。

define('IN_PHPBB', true);
$phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './';
$phpEx = substr(strrchr(__FILE__, '.'), 1);
include($phpbb_root_path . 'common.' . $phpEx);

class AuthClient implements IAuthClient{

protected $user;
protected $auth;

}
于 2013-09-05T13:04:35.370 回答
0

在类中包含文件是不好的做法,因为它将类与您包含的文件耦合在一起,因此无法重用。一种方法是将类存储在一个单独的文件中,并具有这样的构造函数(authclient.class.php):

class AuthClient implements IAuthClient {

    protected $user;
    protected $auth;

    public function  __construct(user $user, auth $auth){

    $this->user = $user;
    $this->auth = $auth;
    $this->user->session_begin();
    $this->auth->acl($user->data);

}

然后有另一个文件,其中包括 phpbb 文件和你的类,然后实例化你的类。

define('IN_PHPBB', true);
$phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './';
$phpEx = substr(strrchr(__FILE__, '.'), 1);
include($phpbb_root_path . 'common.' . $phpEx);
include('authclient.class.php');

$authClient = new AuthClient($user, $auth);
// do further processing with your authclient here

这样,您就可以很好地分离单个关注点(phpbb、类声明、业务逻辑)。如果您最终拥有更多自定义类,您可以使用自动加载器来自动包含您的类。

于 2013-09-05T13:18:12.830 回答
0

为什么要这么做?你的文件是如此的核心程序,你不能只是复制东西并将它们传递给方法,魔法不会发生。

它不是来自 common.php 本身,而是来自整个应用程序。

如果你有:

文件:a.php:

$a = 100;
function double($a) {
return $a*2;
}

文件 b.php

include "a.php";
$b = double($a);
echo $b; // 200

并且您希望 b.php 成为一个类(?!),这样做的坏方法是:

Class B {
    private $_b;

    public function __construct() {
        include "a.php";
        $this->_b = double($a);
    }

    public function double() {
        return $this->_b;
    }
}

您必须重构包含的文件以与对象方式兼容:

Class A {
    public function double($a) {
        return $a*2;
    }
}
Class B {
    private $_a;
    private $_b;
    private $_inst;

    public function __construct() {
        $this->_a = 100;
        $this->_inst = new A();
    }

    public function double($a) {
        $this->_b = $this->_inst->double($this->_a);
        return $this->_b;
    }
}

在您的代码中,您有很多只是函数的函数,而不是没有方法或类实例。您试图通过将它们包含在构造函数中来访问它们,但这不会发生。

User、Auth、Template 等的实例应该被注入到构造函数中,或者注入到使用依赖的单独方法中。在您的代码中, $user 和 $auth 是无状态的,它们不会成为相关类的实例。

如果要将代码重构为类,则必须坚持面向对象的方式。如果你不这样做,那么不要将你的代码注入到一个类中,它不会使它更容易重用。

于 2013-09-05T13:26:13.453 回答