フレームワークを簡潔にまとめました ルート処理

フレームワークでのルート処理を簡潔にまとめました

フレームワーク学習の手助けなどになれば幸いです

実行方法

ドキュメントルートにコードを配置して

/ddd/eee/fff/123 とか /aaa/bbb/ccc のパスにアクセスすると試せます

コード

全て同じ階層に配置してください

.htaccess

ファイルやフォルダがない場合、リクエストをindex.phpにまとめる

<IfModule mod_rewrite.c>
    RewriteEngine On
    
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
</IfModule>

index.php

ルート管理を呼び出して実行

<?php

require_once __DIR__ . '/route.php';

class test {
    /**
    * メインルーチン
    */
    public function run() {
        //サービスコンテナ作成
        $app = new \stdClass;
        
        //ルート管理クラス生成
        $route = new framework\route();
        $route->conf = $this->load_conf();
        
        //サービスコンテナをルート管理クラスに設定
        $app->route = $route;
        $route->app = $app;
        
        try {
            //ルート管理のメインルーチン
            $result =$route->run($_SERVER['REQUEST_URI']);
            
            //結果表示
            $this->result($result);
            
        } catch (framework\route_notfound $e) {
            //ルートエラー時
            
            //ルートエラー表示
            $this->notfound($e);
            
        } catch (Throwable $e) {
            //そのほかのエラー時
            
            throw $e;
        }
        
        //トレース
        $this->trace($route);
    }
    
    /**
    * 設定読み込み
    */
    private function load_conf() {
        return include(__DIR__ . '/route_conf.php');
    }
    
    /**
    * 結果表示
    */
    private function result($result) {
        echo "<pre>";
        echo "result:\n";
        echo $result . "\n";
        echo "</pre>";
    }
    
    /**
    * ルートエラー表示
    */
    private function notfound($e) {
        echo "<pre>";
        echo "<hr>";
        echo "notfound\n";
        echo $e;
        echo "<hr>";
        echo "</pre>";
    }
    
    /**
    * トレース
    */
    private function trace($route) {
        //トレース
        echo "<pre>";
        echo "<hr>";
        echo "target_uri: " . $route->target_uri . "\n";
        
        print_r($route->conf);
        
        print_r($_SERVER);
        echo "<hr>";
        echo "</pre>";
    }
}

(new test)->run();

route.php

フレームワークのルート処理クラス

<?php

namespace framework;

//条件にあう対象のURIがない場合の例外
class route_notfound extends \Exception {}

/**
 * ルート管理
 */
class route {
    //サービスコンテナ
    public $app;
    
    //設定
    public $conf;
    
    //対象のURI
    public $target_uri;
    
    //値
    public $data;
    
    /**
    * メインルーチン
    */
    public function run(string $request_uri) {
        //各種情報作成
        $this->create_info($request_uri);
        
        //実行
        return $this->exec();
    }
    
    /**
    * 各種情報作成
    */
    private function create_info(string $request_uri) {
        //URIからパスだけ取得
        $arr = explode('?', $request_uri);
        $path = $arr[0];
        
        //前後のスラッシュ除去
        $path = trim($path, '/');
        
        $this->target_uri = $path;
    }
    /**
    * 実行
    */
    private function exec() {
        foreach ($this->conf as $row) {
            $pattern = $row[0];
            $callback = $row[1];
            
            //条件にあう対象のURIを探す
            if (preg_match($pattern, $this->target_uri, $data)) {
                //対象外のデータの除去
                array_shift($data);
                
                $this->data = $data;
                
                //コールバック実行
                return $callback($this->app);
            }
        }
        
        //条件にあう対象のURIがない場合
        
        throw new route_notfound();
    }
}

route_conf.php

ルートの設定

<?php

return [
    ['|^$|', function ($app) {
        $text = '';
        $text .= "index\n";
        
        return $text;
    }],
    ['|^aaa/bbb/ccc$|', function ($app) {
        $text = '';
        $text .= "test 1\n";
        
        return $text;
    }],
    ['|^ddd/eee/fff/(\d+)$|', function ($app) {
        $text = '';
        $text .= "test 2\n";
        $text .= print_r($app->route->data, true);
        
        return $text;
    }],
    ['|^ggg/([^\/]+)/hhh/(\d+)$|', function ($app) {
        $text = '';
        $text .= "test 3\n";
        $text .= print_r($app->route->data, true);
        
        return $text;
    }],
];



気づけばプロ並みPHP 改訂版ーーゼロから作れる人になる! [ 谷藤賢一 ]