包装非类代码的最佳实践

时间:2013-09-05 12:59:43

标签: php oop design-patterns phpbb3

在课程中包含和/或包装非课程的好模式是什么?例如,我需要使用这个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

bootstrap.php中

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

LoginController.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();
}
}

3 个答案:

答案 0 :(得分:0)

将代码放入构造函数意味着:

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

  • 此外,方法可以是静态的,因此,不会创建对象的intance,也不会执行代码。

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

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;

}

答案 1 :(得分: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,类声明,业务逻辑)。如果您最终拥有更多自定义类,则可以使用自动加载器自动包含您的类。

答案 2 :(得分:0)

你为什么这样做?你的文件是如此的CORE程序,你不能只是复制东西并在方法中传递它们,魔法不会发生。

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

如果你有:

fila: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是无状态的,它们不会成为相关类的实例。

如果要重构代码以成为类,则必须坚持面向对象的方式。如果你不这样做,那么不要在代码中注入你的代码,这样就不会让它更容易重用。