2017-01-24 24 views
10

Tôi đang xem thư viện bộ định tuyến vankooten danny here. Điều này có vẻ tốt (mặc dù không chắc chắn làm thế nào nó sẽ xử lý dự án từ trung bình đến lớn, ví dụ một trang web thương mại điện tử). Bây giờ, đi bằng ví dụ này là lập bản đồLập bản đồ nhiều tuyến (bộ điều khiển) bằng bộ định tuyến

$router->map('GET','/', 'home.php', 'home'); 
$router->map('GET','/home/', 'home.php', 'home-home'); 
$router->map('GET','/plans/', 'plans.php', 'plans'); 
$router->map('GET','/about/', 'about.php', 'about'); 
$router->map('GET','/contact/', 'contact.php', 'contact'); 
$router->map('GET','/tos/', 'tos.html', 'tos'); 

Hãy nói rằng tôi có một kịch bản mà trang web của tôi có 20-30 trang tĩnh hoặc gần khoảng 50 bộ điều khiển với 2-3 hành động/phương pháp từng.

Làm cách nào để ánh xạ tất cả. Nếu tôi sử dụng phương pháp lập bản đồ ở trên, tôi có thể sẽ có hơn 100 dòng ánh xạ và điều này có vẻ không đúng.

Tôi tin rằng có phải là một cách hay ngắn cắt giảm/ký tự đại diện như kiểm tra nếu có một trang hoặc bộ điều khiển có sẵn, sau đó tải nó hay khác ném một 404.

Làm thế nào để bản đồ tất cả các tuyến đường đúng cách ?

PS. Đưa ra một khoản tiền 50 cho bất kỳ ai sẵn sàng trả lời về cách sử dụng bộ định tuyến nói trên bằng cách sử dụng ký tự đại diện để khớp với bộ điều khiển/phương thức.

Trả lời

6

Việc bạn có thể làm để làm sáng tập tin bộ định tuyến là di chuyển định nghĩa tuyến đường trong một tệp YAML. Bạn vẫn sẽ có nhiều dòng trong YAML của bạn nhưng nó sẽ dễ đọc hơn.

Trong file router.php của bạn, sử dụng mã này:

Đừng quên để thêm YAML phân tích cú pháp symfony để bạn composer.json

use Symfony\Component\Yaml\Yaml; 
$yaml_file = 'routes.yaml'; 
$routes = Yaml::parse(file_get_contents($yaml_file)); 
foreach ($routes as $route_name => $params) { 
    $router->map($params[0],$params[1], $params[2].'#'.$params[3], $route_name); 
} 

// match current request 
$match = $router->match(); 

tập tin của bạn routes.yaml sẽ trông như thế này

index:  ["GET", "/", "home_controller", "display_item"] 
content: ["GET", "/content/[:parent]/?[:child]?", "content_controller", "display_item"] 
article: ["GET", "/article/[:page]", "article_controller", "display_item"] 

Một thứ khác bạn có thể làm để lấy các tệp nhỏ hơn là tách định nghĩa tuyến đường của bạn trong nhiều tệp YAML nhỏ. Ví dụ, một cho các tập tin tĩnh, một cho khu vực admin, một cho phía trước ...

Để làm được một cái gì đó như thế này, bạn phải thay đổi mã router.php một cái gì đó như thế này:

use Symfony\Component\Yaml\Yaml; 
$yaml_files = ['front.yaml', 'static.yaml', 'admin.yaml']; 
foreach ($yaml_files as $yaml_file) { 
    $routes = Yaml::parse(file_get_contents($yaml_file)); 
    foreach ($routes as $route_name => $params) { 
     $router->map($params[0],$params[1], $params[2].'#'.$params[3], $route_name); 
    } 
} 

// match current request 
$match = $router->match(); 

Danny Van Kooten cũng đã thực hiện PHP-Router có hỗ trợ tích hợp cho các tệp YAML.(Nếu bạn nhìn vào mã nguồn, bạn sẽ thấy rằng ông sử dụng phân tích cú pháp Symfony vì vậy cả hai phương pháp này khá giống)

From the doc

YAML định nghĩa đường

base_path: /blog 

routes: 
    index: [/index, someClass.indexAction, GET] 
    contact: [/contact, someClass.contactAction, GET] 
    about: [/about, someClass.aboutAction, GET] 

Router.php

require __DIR__.'/vendor/autoload.php'; 

use PHPRouter\RouteCollection; 
use PHPRouter\Config; 
use PHPRouter\Router; 
use PHPRouter\Route; 

$config = Config::loadFromFile(__DIR__.'/router.yaml'); 
$router = Router::parseConfig($config); 
$router->matchCurrentRequest(); 
3

trong thư viện không có chức năng đó làm điều gì đó như bạn muốn nhưng có một cách khác để làm điều đó, là để lưu trữ những trang trên cơ sở dữ liệu bằng cách đó bạn sẽ có một cái gì đó như thế này dưới đây

//your query 
// "SELECT `method`, `route`, `page`, `name` FROM `static_pages` 
$pages = (query); //your executed query 
if(count($pages) > 0){ 
    foreach($pages as $page){ 
    $router->map($page['method'],$page['route'], $page['target'], (($page['name'] !== null || !empty($page['name'])) ? $page['name'] : null)); 
    } 
} 

tôi hy vọng điều này sẽ giúp

+0

Tôi nhìn vào một cái gì đó phù hợp với đề nghị của bạn, nhưng không chắc chắn về mã mà bạn đăng tải ... Hy vọng trong một vài câu trả lời hơn. Cảm ơn bạn đã gợi ý mặc dù. –

+0

ngay cả trong dòng có một cách thông qua làm cho một mảng nhưng nó sẽ giống như viết nhiều dòng và làm cho tải trên một tệp như '$ pages = array ( mảng ('GET', '/', 'target.php ',' name '), mảng (' GET ','/target ',' target2.php ',' name2 '), mảng (' GET ','/target2 ',' target3.php ', null) // .. và tất cả các mảng được xác định ); foreach ($ pages as $ page) { $ router-> map ($ page [0], $ page [1], $ page [2], $ page [3]); } ' –

2

là một phần của giai đoạn bootstrap nói với các bộ điều khiển của bạn để lập bản đồ bản thân vào một router:

// bootstrap 
$router = new AltoRouter(); 

FooController::mapRoutes($router); 
BarController::mapRoutes($router); 
// etc. 

Mỗi bộ điều khiển được phép sản Tuy nhiên, nhiều tuyến đường cần.

3

Nếu bạn sử dụng bộ định tuyến dựng sẵn như Silex, bạn có thể làm như sau:

$app->get('{route}', function($route) { 
    $dir = "/path/to/my/static/files/"; 
    $file = $dir . $route . '.php'; 
    if (file_exists($file)) { 
     require $file; 
    } else { 
     require '/path/to/custom/404.php'; 
    } 
}); 

Lưu ý rằng Silex và nhiều bộ định tuyến tương tự yêu cầu các tuyến đường phải theo thứ tự ưu tiên. Khi tôi cần sử dụng một bộ định tuyến như thế này, tôi đặt nó ở phía dưới để nó không vô tình bắt bất cứ thứ gì khác. Lưu ý rằng, nếu bạn muốn xây dựng một cái gì đó như tùy chỉnh này, bạn có thể làm điều này - lưu ý tôi không biết mã của bạn trông như thế nào hoặc bạn cần gì - bằng cách thay thế biểu thức chính quy của bạn (trong Ví dụ của Silex, đó là với dấu ngoặc nhọn) và kiểm tra $_SERVER['REQUEST_URI'] đối với cụm từ thông dụng được xây dựng của bạn.

Nếu đây là một ứng dụng tùy chỉnh, bạn có thể không thực sự cần phải qua kỹ sư này.

// routing class 
foreach ($routes as $route) { 
    if ($route != self::DEFAULT_ROUTE) { 
     // do your normal routing logic 
    } else { 
     // check if file exists (as with code above), else send to error 404 
    } 
} 

Sau đó gọi với một cái gì đó như:

$router->map('GET',Router::DEFAULT_ROUTE, 'legacyRouter.php', 'legacy'); 
Các vấn đề liên quan