Основы php-маршрутизации

Я ищу учебник или объяснение того, как сделать очень простую маршрутизацию php.

Например, когда я перехожу по такой ссылке, как: mywebsite.com/users, я хочу запустить метод get класса маршрута, чтобы предоставить данные, так же, как это делает laravel.

Route::get('users', function()
{
    return 'Users!';
});

Может кто-нибудь объяснить, как это сделать или предоставить мне дополнительную информацию?


person Stephan-v    schedule 06.01.2014    source источник
comment
Абсолютно простая вещь, которая могла бы работать? Посмотрите, является ли строка маршрута подстрокой запрашиваемого URL-адреса. Если это так, вызовите функцию.   -  person cHao    schedule 07.01.2014
comment
Есть много способов сделать это. Если вы хотите, чтобы это поведение выполнялось автоматически, используйте фреймворк, который его обеспечивает. Сам PHP не включает такой фреймворк.   -  person Brad    schedule 07.01.2014
comment
вы также можете добиться этого с помощью файла .htaccess, если вы не знакомы с фреймворками.   -  person amarjit singh    schedule 07.01.2014
comment
Часть преимущества программного обеспечения с открытым исходным кодом заключается в том, что вы можете прочитать исходный код...   -  person Denis de Bernardy    schedule 07.01.2014
comment
Это правда, но это немного выше моего понимания, когда документация переходит от одного метода к другому.   -  person Stephan-v    schedule 07.01.2014
comment
Я бы просмотрел исходный код Laravel 3, чтобы узнать, как он внутри обрабатывает маршрутизацию. Исходный код L3 немного проще, чем L4.   -  person Jake Wilson    schedule 07.01.2014


Ответы (3)


В своей наиболее распространенной конфигурации PHP полагается на веб-сервер для выполнения маршрутизации. Это делается путем сопоставления пути запроса с файлом: если вы запрашиваете www.example.org/test.php, веб-сервер фактически будет искать файл с именем test.php в заранее определенном каталоге.

Для наших целей нам пригодится одна функция: многие веб-серверы также позволяют вызывать www.example.org/test.php/hello, и он все еще выполняет test.php. PHP делает дополнительные данные в запрошенном пути доступными через переменную $_SERVER['PATH_INFO']. В этом случае он будет содержать «/hello».

Используя это, мы можем построить очень простой маршрутизатор, подобный этому:

<?php

// First, let's define our list of routes.
// We could put this in a different file and include it in order to separate
// logic and configuration.
$routes = array(
    '/'      => 'Welcome! This is the main page.',
    '/hello' => 'Hello, World!',
    '/users' => 'Users!'
);

// This is our router.
function router($routes)
{
    // Iterate through a given list of routes.
    foreach ($routes as $path => $content) {
        if ($path == $_SERVER['PATH_INFO']) {
            // If the path matches, display its contents and stop the router.
            echo $content;
            return;
        }
    }

    // This can only be reached if none of the routes matched the path.
    echo 'Sorry! Page not found';
}

// Execute the router with our list of routes.
router($routes);

?>

Ради простоты я не стал делать роутер классом. Но с этого момента это тоже не должно быть проблемой.

Предположим, мы назвали этот файл index.php. Теперь мы можем вызвать www.example.org/index.php/hello, чтобы получить красивое «Hello, World!» сообщение. Или www.example.org/index.php/, чтобы получить главную страницу.

«index.php» в этом URL-адресе по-прежнему уродлив, но мы можем исправить это, используя перезапись URL-адреса. В Apache HTTPD вы должны поместить файл .htaccess в тот же каталог со следующим содержимым:

RewriteEngine on
RewriteRule ^(.*)$ index.php/$1

А вот и ты! Ваш собственный маршрутизатор с менее чем 10 строками логического кода (не считая комментариев и списка маршрутов).

person hanzi    schedule 06.01.2014
comment
Есть функция, которая пригодится для нашей цели: многие веб-серверы также позволяют вам вызывать www.example.org/test.php/hello, и он по-прежнему будет выполнять test.php. самые важные шаги. - person Stephan-v; 07.01.2014
comment
Это работает из коробки. Просто поместите куда-нибудь файл PHP с <?php echo $_SERVER['PATH_INFO']; ?> и попробуйте сами. - person hanzi; 07.01.2014

Ну... в Интернете есть много фреймворков для php-маршрутизации. Если вы хотите, вы можете попробовать это с https://packagist.org/search/?q=route. Но, честно говоря, если вы из процедурного мира PHP, это может быть проблематично для вас в первый раз.

Если хотите, вы можете использовать следующий код, написанный Джесси Бойером, который я использовал для своих собственных проектов. Структура вашего приложения должна быть следующей:

[Папка-приложение]

  • index.php
  • .htaccess
  • маршрут.php

маршрут.php

<?php
/**
 * @author      Jesse Boyer <[email protected]>
 * @copyright   Copyright (C), 2011-12 Jesse Boyer
 * @license     GNU General Public License 3 (http://www.gnu.org/licenses/)
 *              Refer to the LICENSE file distributed within the package.
 *
 * @link        http://jream.com
 *
 * @internal    Inspired by Klein @ https://github.com/chriso/klein.php
 */

class Route
{
    /**
    * @var array $_listUri List of URI's to match against
    */
    private static $_listUri = array();

    /**
    * @var array $_listCall List of closures to call 
    */
    private static $_listCall = array();

    /**
    * @var string $_trim Class-wide items to clean
    */
    private static $_trim = '/\^$';

    /**
    * add - Adds a URI and Function to the two lists
    *
    * @param string $uri A path such as about/system
    * @param object $function An anonymous function
    */
    static public function add($uri, $function)
    {
        $uri = trim($uri, self::$_trim);
        self::$_listUri[] = $uri;
        self::$_listCall[] = $function;
    }

    /**
    * submit - Looks for a match for the URI and runs the related function
    */
    static public function submit()
    {   
        $uri = isset($_REQUEST['uri']) ? $_REQUEST['uri'] : '/';
        $uri = trim($uri, self::$_trim);

        $replacementValues = array();

        /**
        * List through the stored URI's
        */
        foreach (self::$_listUri as $listKey => $listUri)
        {
            /**
            * See if there is a match
            */
            if (preg_match("#^$listUri$#", $uri))
            {
                /**
                * Replace the values
                */
                $realUri = explode('/', $uri);
                $fakeUri = explode('/', $listUri);

                /**
                * Gather the .+ values with the real values in the URI
                */
                foreach ($fakeUri as $key => $value) 
                {
                    if ($value == '.+') 
                    {
                        $replacementValues[] = $realUri[$key];
                    }
                }

                /**
                * Pass an array for arguments
                */
                call_user_func_array(self::$_listCall[$listKey], $replacementValues);
            }

        }

    }

}

.htaccess

здесь, во 2-й строке, вместо «/php/cfc/» вам нужно указать имя каталога вашего локального проекта, например «Папка-приложение»

RewriteEngine On
RewriteBase /php/cfc/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule ^(.+)$ index.php?uri=$1 [QSA,L]

index.php

В файле index.php вам нужно написать следующие коды:

<?php 



include "route.php";





/**
 * -----------------------------------------------
 * PHP Route Things
 * -----------------------------------------------
 */

//define your route. This is main page route. for example www.example.com
Route::add('/', function(){

    //define which page you want to display while user hit main page. 
    include('myindex.php');
});


// route for www.example.com/join
Route::add('/join', function(){
    include('join.php');
});

Route::add('/login', function(){
    include('login.php');
});

Route::add('/forget', function(){
    include('forget.php');
});



Route::add('/logout', function(){
    include('logout.php');
});





//method for execution routes    
Route::submit();

Эти вещи отлично работают для меня. Надеюсь, это сработает и для вас...

Удачного кодирования... :)

person tisuchi    schedule 01.07.2015

Документация должна помочь - официальные документы http://laravel.com/docs/quick#routing

Отличное видеоруководство "Laravel с нуля" здесь - https://laracasts.com/series/laravel-from-scratch (посмотрите второй эпизод, может поможет)

person Andreyco    schedule 06.01.2014
comment
Я знаю, как это сделать в laravel, я просто не понимаю основных особенностей того, как это работает. - person Stephan-v; 07.01.2014
comment
URL-адрес сравнивается с шаблонами, зарегистрированными методами Route::get(...) (или post, или любым другим способом). Выигрывает первый соответствующий шаблон, и выполняется его функция обратного вызова. Нет другого пути, кроме как прочитать исходный код, извините. Научит вас многому. - person Andreyco; 07.01.2014