0

クラス内に非クラスを含めたりラップしたりするのに適したパターンは何ですか? たとえば、phpbb ボードにログインするには、この php ファイルhttps://github.com/widop/phpbb3/blob/master/common.phpを使用する必要があります。具体的には、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');

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

3 に答える 3

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 に答える