我开始尝试使用自己的MVC。
我的目标只是实现控制器模型和视图并将它们联系起来,但不幸的是,它在(小)框架方向上进行。
我在根文件夹中有一个基本index.php,它负责路由。 (确定应该创建哪个控制器,将在新创建的控制器实例上调用哪个函数等。)
我直接从url解析控制器,函数和变量(就像codeigniter正在做的那样) 例如: http://baseurl/index.php {router} / User {controller} / get {function to be called} / 1 {variable-0} / desc {variable-1} 而不是使用get方法识别它们(比如?c = mainController& f = function_to_be_called)。
我的问题是(基于我正在做的事情),还有另一种(更好的方法)来实现相同的结果吗?
编辑:
示例请求:http://localhost:8080/ut/User/getUser/1
输出:array(3){[" controller"] => string(4)" User" ["功能"] => string(7)" getUser" ["变量"] => array(1){[2] =>字符串(1)" 1" }
感谢您的关注。
<?php
namespace System;
class UrlParser
{
public static function parseRequest(string $url):?array
{
//default destination if nothing matches
$destination = '404';//self::$routes['index'];
//the order: controller to be loaded, function to be called and parameters etc...
$hierarchical_call = array();
//remove www : [I know its not generic]
//TODO: check base url if it contains www, don't remove www
$url = str_replace('www', '', $url);
// check for a trailer slash, if not add it
$url = substr($url, strlen($url) - 1, 1) === '/' ? $url : $url . '/';
// split url into base url and rest
$url_parts = explode(baseurl, $url);
//url has more content
if (count($url_parts) > 1) {
$rest_url = $url_parts[1];
/*add leading slash for regex, it is easier to get the string between two slashed insteadof [A-Z]*/
$rest_url = substr($rest_url, 0, 1) === '/' ? $rest_url : '/' . $rest_url;
/*
* use regex to get the first part which is between / and /
* if it is index.php than check if url parts has any other request
*/
$pattern = '/[a-zA-Z0-9_\.]+/';
preg_match_all($pattern, $rest_url, $request_parts, PREG_SET_ORDER);
/*
* PREG_PATTERN_ORDER
* Orders results so that $matches[0] is an array of full pattern matches,
* $matches[1] is an array of strings matched by the first parenthesized subpattern, and so on.
*/
for ($i = 0; $i < count($request_parts); $i += 1) {
//the requested file is determined add the remaining parts to it
if (strlen($request_parts[$i][0]) > 0 && $request_parts[$i][0] !== 'index.php') {
$hierarchical_call[] = $request_parts[$i][0];
}
}
}
return $hierarchical_call;
}
}
答案 0 :(得分:2)
Php具有内置功能 - parse_url。
$url = 'http://localhost:8080/ut/User/getUser/1';
$parsed = parse_url($url);
var_dump($parsed);
array(4) {
["scheme"]=> string(4) "http"
["host"]=> string(9) "localhost"
["port"]=> int(8080)
["path"]=> string(18) "/ut/User/getUser/1"
}
在explode
路径之后:
$route = explode("/", $parsed['path']);
var_dump($route);
array(5) {
[0]=> string(0) ""
[1]=> string(2) "ut"
[2]=> string(4) "User"
[3]=> string(7) "getUser"
[4]=> string(1) "1"
}
答案 1 :(得分:1)
首先,您不需要解析完整的网址,因为您可以检索用户的通话
在$_SERVER['REQUEST_URI']
...但我想这不是那么优雅。
至于拆分该URI路径,您应该实际使用正则表达式。在您的具体示例中,正则表达式为:
'#^/ut/(?P<controller>[\w]+)/(?P<method>[\w]+)/(?P<id>[\d]+)$#i'
实时样本:here
您可以阅读有关如何制作路由代码here的更多信息,但除非您将此作为学习经验,否则您可能应该使用现有的库,例如FastRoute或Symfony&# 39; s standalone router。