[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Получить данные из метода
paul85
Всем привет!

Вот хочу замутить такую штуку: указывать в методе массив с параметрами, которые он может получать. Имеется ввиду GET|POST. Вроде все хорошо, но эти данные нужно каким-то образом заполучить в диспетчере, в тот момент, когда метод еще не вызывался.

Есть какие-нибудь трюки а-ля reflection с помощью которых это можно сделать? То есть получить значение переменной еще до того как создан экземпляр класса и вызван метод.

Ну либо указывать параметры определенным образом... Главное, чтобы они были перед глазами во время работы с кодом. Чтобы не нужно было открывать какие-то другие файлы, или мотать скроллингом в начало/конец файла. В то же время, если ничего не указано, то это означает, что метод не ждет никаких параметров. Все, что не разрешено - то запрещено. То есть дополнительные вызовы при выполнении не канают. Можно просто забыть их указать, например.

Ну вот такая идея... Возможно ли вообще?

sergeiss
Цитата (paul85 @ 6.05.2015 - 21:27)
Вроде все хорошо, но эти данные нужно каким-то образом заполучить в диспетчере, в тот момент, когда метод еще не вызывался.

Ничё не понял.... Объясни подробнее.

_____________
* Хэлп по PHP
* Описалово по JavaScript
* Хэлп и СУБД для PostgreSQL

* Обучаю PHP, JS, вёрстке. Интерактивно и качественно. За разумные деньги.

* "накапливаю умение телепатии" (С) и "гуглю за ваш счет" (С)

user posted image
paul85
Цитата (sergeiss @ 6.05.2015 - 22:33)
Ничё не понял.... Объясни подробнее.

Ок. =)

После того, как роутер нашел маршрут, управление передается на диспетчер. Он выполняет проверки, создает экземпляр необходимого класса и запускает метод через call_user_func.

Когда запрашивают site.com/foo и site.com/foo?query=123 получается вызов одного и того же метода. С одним и тем же результатом. Но URL с точки зрения поисковых машин, при этом разные.

Идея в том, чтобы сообщить диспетчеру, ждет ли метод (чисто теоретически. Не валидация) какие-либо параметры. Или они ему нафиг не нужны ни при каких обстоятельствах. И если не ждет, то высвечивать 404 еще до вызова целевого метода. Ну желательно так, хоть и не строго обязательно.

Я бы хотел указывать ожидаемые параметры непосредственно в целевом методе, ну хотя бы в виде обычного массива. Прямо вначале, скажем $expected_params = ['page', 'partnumber']. Для удобства, чтобы не рыскать по дополнительным файлам. Вопрос в том, как получить этот array еще до того, до вызова самого метода? В момент работы диспетчера?

Можно, конечно, вызывать целевой метод, оттуда же записывать в свойства объекта вышеозначенный массив, и в деструкторе проверять, а ожидал ли метод параметры? И если нет, то отдавать 404. Круто с точки зрения конечного результата. НО! Нафига нам отрабатывать всю бизнес-логику, вызывать модели, готовить результат, заполнять экземпляр шаблонизатора, чтобы в самый последний момент сказать "Ууупс, а на этот запрос нужно ответить 404". Глупость же...

P.s. Пока что реализовал, ну скажем так, через роутер. Условно говоря. Но проблема такая: существуют неспецифические маршруты вида controller/method, - что в запросе указано, такой класс/метод будет вызван. Мы не знаем ожидаются ли параметры по именованному маршруту, или нет. Не можем указать явным образом в маршруте, короче говоря...
sergeiss
Цитата (paul85 @ 6.05.2015 - 23:09)
P.s. Пока что реализовал, ну скажем так, через роутер. Условно говоря. Но проблема такая: существуют неспецифические маршруты вида controller/method, - что в запросе указано, такой класс/метод будет вызван. Мы не знаем ожидаются ли параметры по именованному маршруту, или нет. Не можем указать явным образом в маршруте, короче говоря...

Роутеры, классы, методы, маршруты, диспетчеры... Ничё не понятно wink.gif А самое главное, что не понятно - почему ты не можешь для каждой связки "класс/метод" определить заранее, могут ли быть параметры? И почему ты не можешь эту проверку сделать в самом начале, до работы твоей бизнес-логики?


_____________
* Хэлп по PHP
* Описалово по JavaScript
* Хэлп и СУБД для PostgreSQL

* Обучаю PHP, JS, вёрстке. Интерактивно и качественно. За разумные деньги.

* "накапливаю умение телепатии" (С) и "гуглю за ваш счет" (С)

user posted image
brevis
Цитата (paul85 @ 6.05.2015 - 21:27)
reflection

Через неё родимую. Первый попавшийся пример.

_____________
Чатик в телеге
chee
Если я правильно понял, что тебе нужно, то:
1. Объявляешь метод в котроллере, у метода указываешь параметры, которые для него допустимы;
2. Идешь в диспатчер, после того как роутер отработал и ты нашел контроллер и метод, берешь объект контроллера через рефлексию, находить там нужный метод через рефлексию и получаешь список параметров через рефлексию (как в посте выше)
3. Делаешь дифф между списком пришедших параметров и списком параметров метода полученые через рефлексию, если все ок передаёшь управление методу, если не ок, то отдаешь клиенту 400 Bad request
4. ???
5. PROFIT!!!

_____________
Люди, имеющие низкий уровень квалификации, делают ошибочные выводы, принимают неудачные решения и при этом неспособны осознавать свои ошибки в силу низкого уровня своей квалификации
paul85
brevis, chee - немного не те параметры я ожидаю. Они не описаны в заголовке метода. Метод принимает array от диспетчера, но он не содержит полей из GET.

Задача каким-то образом в теле метода объявить переменную, чтобы она была доступна на чтение до выполнения этого метода. А что если я ее объявлю статической? Или может быть как-то через константы?

Просто основная загвоздка именно в месте объявления. Так-то можно создать отдельный файл, с именем точно таким же, как и класс. А там объявить массив многомерный. array('methodname'=>array('page', 'partnumber')). И никаких проблем. Но. Неудобно! То есть если я захочу объявить доступные GET параметры для метода, мне надо будет бежать создавать/редактировать файл... Так запрыгаешься...


Цитата (sergeiss @ 6.05.2015 - 23:57)
А самое главное, что не понятно - почему ты не можешь для каждой связки "класс/метод" определить заранее, могут ли быть параметры?

Могу. Так и делаю на данный момент. Но есть неспецефические маршруты вида:
$router->map('GET|POST', '/[:controller]/[:method]?/[:id]?/[:id2]?/[:id3]?', array('method'=> 'show'), 'lazy');

А так я сделал в целом:

$router = new AltoRouter();
$router->map('GET', '/page/[:pagename]', array('controller'=>'page','method'=>'show'), 'page_handler');
$router->map('GET|POST', '/admin/[:controller]?/[:method]?/[:id]?/[:id2]?/[:id3]?', array('controller' => 'index', 'method'=>'show', 'subfolder'=>'admin'), 'admin');
$router->map('GET|POST', '/[:controller]/[:method]?/[:id]?/[:id2]?/[:id3]?', array('method'=> 'show'), 'lazy');
$router->map('GET' , '/sitemap.xml', array('controller'=>'sitemap', 'method'=>'show'), 'sitemap');
$router->map('GET', '/', array('controller'=>'index', 'method'=>'show'),'index_page');


$allowedGetParams = array(
'*' => array(
'reflog'=>true,
),

'page_handler'=> array(
'p'=>true,
),
);


Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.