Форум программистов, компьютерный форум, киберфорум
PHP: Фреймворки
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.80/15: Рейтинг темы: голосов - 15, средняя оценка - 4.80
0 / 0 / 0
Регистрация: 21.04.2015
Сообщений: 23

ЧПУ своими руками

07.07.2015, 21:20. Показов 3114. Ответов 18
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток. У меня загвоздка на ЧПУ. Прописал правила в .htaccess, чтоб все запросы шли на index.php. Дальше парсю полученную ссылку и подгружаю нужный класс и его метод. Вот тут главный вопрос! Как определить, что вызван метод, которому нужно передавать аргументы?
Например, есть 2 метода
viewOne($id) и viewAll()
PHP
1
2
exmp.ru/city/viewAll
exmp.ru/city/viewOne/3
вызываю метод view класса city и передаю туда цифру 3.
Во втором, метод view того же класса без параметров.

Как определить на момент include_once в index.php какой метод вызывается, принимает ли она аргументы и сколько?
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
07.07.2015, 21:20
Ответы с готовыми решениями:

Валидация данных. MVC своими руками
Здравствуйте. Помогите разобраться с логикой работы валидаторов в mvc. Как правильно организовать этот процесс? К примеру, валидация...

Человекопонятный url (или ЧПУ) своими руками
Наверное, этот вопрос уже "заезженный" и сто раз обсужденный. Но поиск по форуму ничего не дал. По этому подниму я его еще раз. В...

ОС своими руками
Здравствуйте, форумчане, появился вот такой вопрос: возможно ли создать простейшую ос руками простого программиста, заранее знаю что ничего...

18
Почетный модератор
Эксперт HTML/CSSЭксперт PHP
 Аватар для KOPOJI
16844 / 6724 / 880
Регистрация: 12.06.2012
Сообщений: 19,967
07.07.2015, 21:26
Обычно это делается при помощи explode, например.
PHP
1
$uri = explode('/', trim($url, '/'));
А дальше уже смотрите: обычно первое означает контроллер, второе - метод, все остальное - аргументы.
Дальше либо передавать метод с аргументами как есть (т.е. биндить их - call_user_func_array и т.п.), если, конечно, такой класс и метод существует - class_exists+method_exists, либо воспользоваться Reflection Api, чтобы проверить, существует ли такой метод и, заодно, проверить и количество аргументов этого метода.
0
0 / 0 / 0
Регистрация: 21.04.2015
Сообщений: 23
07.07.2015, 21:51  [ТС]
А если метод не принимает параметров? В этом загвоздка. Я делаю абстрактный класс. И какие методы в дочерних понадобятся мне, я не знаю.
Имя контроллера, экшина и параметр я получил. Дальше непонятно какой метод будет вызван (с каким кол-вом параметров или без них)
0
Почетный модератор
Эксперт HTML/CSSЭксперт PHP
 Аватар для KOPOJI
16844 / 6724 / 880
Регистрация: 12.06.2012
Сообщений: 19,967
07.07.2015, 21:56
Я же сказал, есть Reflection Api. Нет такого класса/метода/параметров (больше или меньше) - выдали ошибку и успокоились.

Добавлено через 22 секунды
Цитата Сообщение от Miciew Посмотреть сообщение
Дальше непонятно какой метод будет вызван (с каким кол-вом параметров или без них)
как это непонятно. Вы что, не понимаете свой код?
0
0 / 0 / 0
Регистрация: 21.04.2015
Сообщений: 23
07.07.2015, 21:59  [ТС]
Цитата Сообщение от KOPOJI Посмотреть сообщение
Вы что, не понимаете свой код?
Я делаю минифреймворк (велосипед, но!). Закладываю фундамент, скажем так. Дочерних не известно сколько будет у меня моделей.
0
Почетный модератор
Эксперт HTML/CSSЭксперт PHP
 Аватар для KOPOJI
16844 / 6724 / 880
Регистрация: 12.06.2012
Сообщений: 19,967
07.07.2015, 22:02
А каким образом тут модели вообще? Это все должно решаться в роутере, а не в модели.
В роутере вы проверяете, правильно ли пользователь ввел адрес, и если все ок - запускаете все. Если нет - то приложению нет смысла целиком разворачиваться - отобразили ошибку (или вызвали соответствующий метод соответствующего контроллера) и забыли.
0
0 / 0 / 0
Регистрация: 21.04.2015
Сообщений: 23
07.07.2015, 22:04  [ТС]
Цитата Сообщение от KOPOJI Посмотреть сообщение
Вы что, не понимаете свой код?
Я делаю минифреймворк (велосипед, но!). Закладываю фундамент, скажем так. Дочерних не известно сколько будет у меня моделей.
Цитата Сообщение от KOPOJI Посмотреть сообщение
А каким образом тут модели вообще?
Сорян, попутал)) Имел в виду, что в экшин надо передать параметр, чтоб потом в модели ее использовать.
0
4 / 4 / 1
Регистрация: 28.05.2014
Сообщений: 77
07.07.2015, 22:04
Fortran
1
2
3
4
5
6
7
8
9
10
11
12
AddDefaultCharset UTF-8
 
Options All -Indexes
 
<FilesMatch ".(htaccess|htpasswd|tpl|kwm)$">
    Order Allow,Deny
    Deny from all
</FilesMatch>
 
RewriteEngine on
 
RewriteRule ^news/it/([A-z0-9]+)/comment/id/([0-9]+)/$ ?page=news&page2=it&name=$1&comment=$2
0
0 / 0 / 0
Регистрация: 21.04.2015
Сообщений: 23
07.07.2015, 22:09  [ТС]
Цитата Сообщение от WestlE Посмотреть сообщение
RewriteRule
Это правило прописано, я же сказал в самом начале
0
Почетный модератор
Эксперт HTML/CSSЭксперт PHP
 Аватар для KOPOJI
16844 / 6724 / 880
Регистрация: 12.06.2012
Сообщений: 19,967
07.07.2015, 22:22
Цитата Сообщение от Miciew Посмотреть сообщение
в экшин надо передать параметр, чтоб потом в модели ее использовать
так передавайте, кто мешает?)
Вот, если на простом примере то, про что я говорил
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class Test
{
    function aa() {}
    function bb($foo, $bar, $lol=NULL) {}
}
 
$url = 'test/bb/foo/bar/lol';
$args = explode('/', trim($url, '/'));
$controller = array_shift($args);
$action = array_shift($args);
 
//либо так, простая проверка только на существование метода
var_dump(method_exists($controller, $action));
 
//или, что, имхо, лучше:
$method = new \ReflectionMethod($controller, $action);
var_dump(
    $method->getNumberOfRequiredParameters(),
    $method->getNumberOfParameters()
);
 
if($method->getNumberOfRequiredParameters() > count($args))
{
    //ошибка, количество аргументов меньше минимального количества!
}
else
{
    //по желанию можно добавить проверку на то, что аргументов меньше, чем возможно:
    if($method->getNumberOfParameters() < count($args))
    {
        //ошибка, количество переданных аргументов больше возможных
    }
    else
    {
        //все вроде ок, можно вызывать метод
    }
}
0
0 / 0 / 0
Регистрация: 21.04.2015
Сообщений: 23
07.07.2015, 22:29  [ТС]
Цитата Сообщение от KOPOJI Посмотреть сообщение
так передавайте, кто мешает?)
Так то никто не мешает, если использовать заранее известный метод)

PHP
1
2
3
4
5
$controller = new $controllerClass;
        
        $controller->controller = str_replace('Controller', '', $controllerClass);
        $controller->action = str_replace('action', '', $action);
        $controller->$action();
Я вот что делал. Создаю экземпляр класса, его экшин. Вызываю экшин по имени. Но что ему нужно для работы я заранее не знаю.

Щас попробую разобраться в Reflection. Может и действительно то, что нужно)
0
Почетный модератор
Эксперт HTML/CSSЭксперт PHP
 Аватар для KOPOJI
16844 / 6724 / 880
Регистрация: 12.06.2012
Сообщений: 19,967
07.07.2015, 22:50
Цитата Сообщение от Miciew Посмотреть сообщение
Щас попробую разобраться в Reflection
Попробуйте
0
0 / 0 / 0
Регистрация: 21.04.2015
Сообщений: 23
08.07.2015, 03:30  [ТС]
В общем, нагромоздил вот такой кусок кода. Может кто-нибудь подскажет, можно ли его сократить

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
if($RefParentClass = new ReflectionMethod($controllerClass, $actionClass))
        {
            $controller = new $controllerClass;
            $controller->controller = str_replace('Controller', '', $controllerClass);
            $controller->action = str_replace('action', '', $actionClass);
 
            if($RefParentClass->getNumberOfParameters())
            {
                if(!empty($_GET['id']) && is_numeric($_GET['id'])){
                    $id = $_GET['id'];
                }  else {
                    throw new Exception('Не верный ID');
                }
                $controller->$actionClass($id);
            } else{
                $controller->$actionClass();
            }
            
            
        }
        else {
            throw new Exception('Запрошенной страницы не существует!');
        }
И еще. В классе Router можно обрабатывать не только GET же? Тут же и для POST запроса можно правила прописать?
0
Почетный модератор
Эксперт HTML/CSSЭксперт PHP
 Аватар для KOPOJI
16844 / 6724 / 880
Регистрация: 12.06.2012
Сообщений: 19,967
08.07.2015, 07:50
Странно. Я думал, вы используете ЧПУ и единую точку входа
Цитата Сообщение от Miciew Посмотреть сообщение
exmp.ru/city/viewOne/3
а в последнем коде вы используете $_GET['id']. Очень странно и выглядит как костыль. А если параметров будет больше, чем один? Можно же все динамически сделать.
И, имхо, проверка id уже как раз не относится к роутеру - это лучше делать в контроллере в соответствующем методе, а в роутере только проверять, есть ли такой метод и количество аргументов.

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Test
{
    function bb($foo, $bar, $lol=NULL) { var_dump($foo, $bar, $lol); }
}
 
$url = 'test/bb/foo/bar';
$args = explode('/', trim($url, '/'));
$controllerClass = array_shift($args);
$action = array_shift($args);
 
$method = new \ReflectionMethod($controllerClass, $action);
 
 
if($method->getNumberOfRequiredParameters() > count($args) || $method->getNumberOfParameters() < count($args))
{
    throw new Exception('Запрошенная страница не найдена');
}
else
{
    $controller = new $controllerClass;
    $controller->controller = str_replace('Controller', '', $controllerClass);
    $controller->action = str_replace('action', '', $action);
    $method->invokeArgs($controller, $args);
}
или
PHP
1
call_user_func_array(array($controller, $action), $args);
вместо invokeArgs, если не нравится Reflection.
А уже что там с аргументами, какой id и т.п., имхо, надо проверять в контроллере.
0
0 / 0 / 0
Регистрация: 21.04.2015
Сообщений: 23
08.07.2015, 15:14  [ТС]
Цитата Сообщение от KOPOJI Посмотреть сообщение
Я думал, вы используете ЧПУ и единую точку входа
Именно это я и пытаюсь сделать. На счет проверки полученных параметрах в контроллере согласен, гибче будет))


PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
if($RefParentClass = new ReflectionMethod($controllerClass, $actionClass))
{
      $controller = new $controllerClass;
      $controller->controller = str_replace('Controller', '', $controllerClass);
      $controller->action = str_replace('action', '', $actionClass);
 
      if($RefParentClass->getNumberOfParameters())
      {
           $controller->$actionClass($param);
      } else{
             $controller->$actionClass();
        } 
 }
 else {
      throw new Exception('Запрошенной страницы не существует!');
}
Так вернее? Потом в нужном контроллере парсить параметры в запросе $param? Я вот так понял все это дело
0
Почетный модератор
Эксперт HTML/CSSЭксперт PHP
 Аватар для KOPOJI
16844 / 6724 / 880
Регистрация: 12.06.2012
Сообщений: 19,967
08.07.2015, 15:55
Лучший ответ Сообщение было отмечено Miciew как решение

Решение


я вам дал почти готовый код. Вам надо было всего лишь изменить его на свой. К чему эти ненужные if-else ?
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
if (
    ($RefParentClass = new ReflectionMethod($controllerClass, $actionClass)) &&
     $RefParentClass->getNumberOfRequiredParameters() <= count($param) &&
     $RefParentClass->getNumberOfParameters() >= count($param)
)
{
      $controller = new $controllerClass;
      $controller->controller = str_replace('Controller', '', $controllerClass);
      $controller->action = str_replace('action', '', $actionClass);
      $RefParentClass->invokeArgs($controller, $param);
}
 else {
      throw new Exception('Запрошенной страницы не существует!');
}
$param должно быть массивом, где хранятся все параметры.

Добавлено через 54 секунды
и непонятно совершенно, зачем вы объект ReflectionMethod называете как RefParentClass
0
0 / 0 / 0
Регистрация: 21.04.2015
Сообщений: 23
08.07.2015, 16:16  [ТС]
Цитата Сообщение от KOPOJI Посмотреть сообщение
К чему эти ненужные if-else ?
К тому, что вызываемый экшин может не принимать параметров.

Не до конца разобрался с этим API, видимо. Всем спасибо за помощь
0
Почетный модератор
Эксперт HTML/CSSЭксперт PHP
 Аватар для KOPOJI
16844 / 6724 / 880
Регистрация: 12.06.2012
Сообщений: 19,967
08.07.2015, 16:26
Miciew, код выше отлично вызовет метод и без аргументов, если у метода их нет.
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
kopoji@kopoji-System-Product-Name:~$ php -f /var/www/test/index2.php
ok
kopoji@kopoji-System-Product-Name:~$ cat /var/www/test/index2.php
<?php
 
class Test
{   function aa(){ echo 'ok', PHP_EOL; }
    function bb($foo, $bar, $lol=NULL) { var_dump($foo, $bar, $lol); }
}
 
$url = 'test/aa';
$args = explode('/', trim($url, '/'));
$controllerClass = array_shift($args);
$actionClass = array_shift($args);
 
 
if (
    ($RefParentClass = new ReflectionMethod($controllerClass, $actionClass)) &&
     $RefParentClass->getNumberOfRequiredParameters() <= count($args) &&
     $RefParentClass->getNumberOfParameters() >= count($args)
)
{
      $controller = new $controllerClass;
      $controller->controller = str_replace('Controller', '', $controllerClass);
      $controller->action = str_replace('action', '', $actionClass);
      $RefParentClass->invokeArgs($controller, $args);
}
 else {
      throw new Exception('Запрошенной страницы не существует!');
}
0
0 / 0 / 0
Регистрация: 21.04.2015
Сообщений: 23
08.07.2015, 16:33  [ТС]
Да, я заметил) Буду разбираться с API. Удобная штука, не знал о ней ничего.

Всем еще раз спасибо, особенно KOPOJI.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
08.07.2015, 16:33
Помогаю со студенческими работами здесь

Windows XP своими руками
доброго времени суток . ПОдскажите черз какой софт можно сделать образ ХР самому ну тоесть выкинуть все лишнее типо игр, заставок ,...

Проектор своими руками
Как сделать проектор своими руками . Поделитесь опытом , кто имеющий ( описывайте тот тип проектора который знаете)

Colorpicker своими руками
Здравствуйте , Помогите пожалуйста сделать задание. Создать клиентский скрипт на языке JavaScript, выполняющий действия в соответствии с...

Arduino - своими руками
Вот тут такая накладка вышла, ПДУ надо сделать и вообще сложностей масса. Вот думаю может можно собрать arduino pro mini самому но в этом...

DLL своими руками
Здравствуйте, смотрю на пример создания DLL http://vbcorner.narod.ru/faq/dll.html Хотел узнать когда создам DLL есть возможность как то...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru