@Banny_Boom

Как получить GET параметры в MVC?

Гугл, местный поиск результатов кошерных не дал, вот и пишу.

Как в MVC получить $_GET параметры?
site/controller/action/?get...
Не вариант, некрасиво и не нравится...
хотелось бы
site/controller/action?get

Как вариант резать explode('?',url)
1 часть - url
2 часть - get

2 часть тоже обработать и вернуть массив get парраметров...

Но мне кажется это бред, как лучше это реализовать?
  • Вопрос задан
  • 537 просмотров
Пригласить эксперта
Ответы на вопрос 2
Akdmeh
@Akdmeh
PHP, Yii2, Music
1) Функция parse_url
2) переменные в $_SERVER, в одном из них должна быть необходимая информация (кажется, в QUERY_STRING, но проверьте сами точнее)
3) Посмотрите, как это решается в готовых микрофреймворках, а еще лучше - используйте готовые микрофреймворки, вы получите намного больше пользы от этого и будете меньше тратить времени на поддержку кода фреймворка.
Ответ написан
Комментировать
copist
@copist
Empower people to give
Позвольте всобачить сюда свой велосипед. Так сказать, самый сок.

Пример разбора параметров $_GET:
<?php
class AppRequest {

	protected $_get;

	/**
	 * Normalizes the request data
	 * This method strips off slashes in request data if get_magic_quotes_gpc() returns true
	 */
	protected function normalizeRequest() {
		if(function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) {
			if(isset($_GET)) {
				$_GET = $this->stripSlashes($_GET);
			}
		}
		if(isset($_GET)) {
			$this->_get = $_GET;
		}
	}

	/**
	 * Returns the named GET parameter value
	 * If the GET parameter does not exist, the second parameter to this method will be returned
	 * @param string $name the GET parameter name
	 * @param mixed|null $default the default parameter value if the GET parameter does not exist
	 * @return mixed|null the GET parameter value
	 */
	public function getQueryVar($name, $default = null) {
		if (isset($this->_get[$name])) {
			return $this->_get[$name];
		}
		return $default;
	}

	/**
	 * Returns the request URI portion for the currently requested URL
	 * @return string the request URI portion for the currently requested URL
	 */
	public function getRequestUri() {
		static $requestUri;
		if (!isset($requestUri)) {
			if(isset($_SERVER['REQUEST_URI'])) {
				$requestUri = $_SERVER['REQUEST_URI'];
				if(!empty($_SERVER['HTTP_HOST'])) {
					if(strpos($requestUri, $_SERVER['HTTP_HOST']) !== false) {
						$requestUri = preg_replace('/^\w+:\/\/[^\/]+/', '', $requestUri);  // remove schema and host name "schema://host/"
					}
				} else {
					$requestUri = preg_replace('/^(http|https):\/\/[^\/]+/i', '', $requestUri); // remove schema and host name "schema://host/"
				}
			}
		}
		return $requestUri;
	}
}

весь код класса AppRequest

Вариант логики разбора строки URL:
Если есть какая-нибудь логика для коротких человеко-читаемых URL, то надо привести их к формату
controller/action + все дополнительные параметры из URL перенести в переменные $_GET или завести для них отдельный специальный массив в класса AppRequest. Такое можно сделать путём статического разбора строки или регулярными выражениями.

Пример:
на вход / -> на выход home/index
на вход /my-home-page/ -> на выход home/welcome
на вход /photo/summer.jpg -> на выход gallery/view + $_GET['image-alias'] = 'summer.jpg'
на вход /wiki/path/to/article.html -> на выход wiki/view + $_GET['page-alias'] = 'path/to/article'

После этого преобразовать имя контроллера в имя класса, а имя действия - в метод (как в моём велосипеде).
class HomeController {
    function indexAction() {
        echo "Welcome!";
    }
}

Полный пример разбора в классе AppRouter + файл конфигурации с правилами
Пример правил для указанных выше 4х случаев:
// Incoming URL mathing rules
$rules = array(
	// if request URI is empty
	'' => array('home', 'index'), // -> код контролера + код действия

	// if request URI looks like /my-home-page/ 
	'/^my-home-page$/' => array('HomeController', 'indexAction'), // -> имя класса контроллера + имя функции

	// if request URI looks like /photo/summer.jpg
	'/^/photo/(?<alias>.+)$/' => array('gallery', 'view', array('image-alias' => ':alias')),

	// if request URI looks like /wiki/path/to/article.html
	'^/wiki/(?<alias>.+)\.html$' => array('wiki', 'view', array('page-alias' => ':alias')),
);


А можно поменять роутинг так, чтобы под каждое действие был отдельный класс
class HomeIndex {
    function run() {
        return new AppResponse("Welcome!");
    }
}

В некоторых микро-фреймворках можно даже функции назначать
function home_index() {
    return new AppResponse("Welcome!");
}
$routes = array(
    '/my-home-page/' => 'home_index',
);

И даже использовать анонимные функции, тогда у них вся логика приложения вообще в один конфигурационный файл вмещается
$routes = array(
    '/my-home-page/' => function() { return new AppResponse("Welcome!"); },
);
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы