2

内部で使用するための独自のフレームワークを構築しようとしています。私はこのような構造を得ました:

index.php
boot /
    booter.php
application /
     controllers /
           indexcontroller.php
core /
    template.class.php
    model.class.php
    controller.class.php
    cache / 
         memcached.php
    something /
         something.php

Booter.php には以下が含まれます: (現在、コア ディレクトリにあるファイルのみで動作しています):

class Booter
{
private static $controller_path, $model_path, $class_path;

public static function setDirs($controller_path = 'application/controllers', $model_path = 'application/models', $classes_path = 'core')
{
    self::$controller_path = $controller_path;
    self::$model_path      = $model_path;
    self::$class_path      = $classes_path;

    spl_autoload_register(array('Booter', 'LoadClass'));
    if ( DEBUG ) 
        Debugger::log('Setting dirs...');
}

protected static function LoadClass($className) 
{
    $className = strtolower($className);

    if ( file_exists(DIR . '/' . self::$model_path . '/' . $className . '.php') ) 
    {
        require(DIR . '/' . self::$model_path . '/' . $className . '.php');
    }       
    else if ( file_exists(DIR . '/' . self::$class_path . '/' . $className . '.class.php') ) 
    {
        require(DIR . '/' . self::$class_path . '/' . $className . '.class.php');
    }
    else if ( file_exists(DIR . '/' . self::$controller_path . '/' . $className . '.php') )
    {
        require(DIR . '/' . self::$controller_path . '/' . $className . '.php');
    }

    if ( DEBUG )
        Debugger::log('AutoLoading classname: '.$className);
}
}

私のアプリケーション/コントローラ/インデックスコントローラは次のようになります:

<?
class IndexController extends Controller
{
     public function ActionIndex()
     {
          $a = new Model; // It works
          $a = new Controller; //It works too
     }
}

?>

そして、ここに私の質問があります:

[質問1]

私のコードは現在次のように動作しています:

$a = new Model; // Class Model gets included from core/model.class.php

名前空間を持つクラスによってインクルード ファイルを実装するにはどうすればよいですか? 例えば:

$a = new Cache\Memcached; // I would like to include file from /core/CACHE/Memcached.php
$a = new AnotherNS\smth; // i would like to include file from /core/AnotherNS/smth.php 

等々。名前空間の処理を作成するにはどうすればよいですか?

[質問2]

クラス、コントローラー、およびモデルに単一の自動ロードを使用することは良い習慣ですか、それとも 3 つの異なるメソッドで 3 つの異なる spl_autoload_register を定義する必要がありますか?その理由は?

4

2 に答える 2

3

通常、アプリケーションのルートにbootstrap.phpあるフォルダー内にファイルがあります。conf私のコードは通常src、ルートにもあるフォルダー内にあるため、これは私にとっては問題なく機能します。

<?php

define('APP_ROOT', dirname(__DIR__) . DIRECTORY_SEPARATOR);

set_include_path(
    implode(PATH_SEPARATOR,
        array_unique(
            array_merge(
                array(
                    APP_ROOT . 'src', 
                    APP_ROOT . 'test'
                ),
                explode(PATH_SEPARATOR, get_include_path())
            )
        )
    )
);

spl_autoload_register(function ($class) {
    $file = sprintf("%s.php", str_replace('\\', DIRECTORY_SEPARATOR, $class));
    if (($classPath = stream_resolve_include_path($file)) != false) {
        require $classPath;
    }
}, true);

これを「ブーター」クラスに一般化し、ディレクトリをインクルード パスに追加できます。適切に定義された名前空間名があれば、衝突の問題はありません。

編集:これは、 PSR-1 に従っている場合に機能します。

于 2013-05-22T12:00:37.873 に答える
2

質問1:

オートローダーで、\ (名前空間) を に変更しますDIRECTORY_SEPARATOR。これはうまくいくはずです:

protected static function LoadClass($className) 
{
    $className = strtolower($className);
    $className = str_replace('\\', DIRECTORY_SEPARATOR, $className);
...
}

DIRECTORY_SEPARATOR特にソフトウェアが他のプラットフォームで使用される可能性がある場合は、常に を使用してください。

質問2:

私は1つを使用し、クラスを名前空間で分離します。ただし、それは、フレームワークをどのように構築したいか、コードをどのように分離するかにかかっていると思います。他の誰かがその質問によりよく答えることができるかもしれません。

于 2013-05-22T00:31:48.197 に答える