如何在自定义 PHP MVC 中更改 link (nameOfController?a=1&b=5&c=20&d=30)
How to Change link (nameOfController?a=1&b=5&c=20&d=30) in Custom PHP MVC
我正在尝试借助 link uisng GET 方法中的值从数据库中检索一些数据...并使用自定义 php MVC..
由于我还是初学者,我不知道如何访问从第 1 页的表单发送到第 2 页的另一个表单的数据..
这是常规方式。
例子
page1.php
<form method="GET" action="<?php echo URL"./page2.".php ;?> ">
<select name="a">
<option value="1">Option 1</option>
<option value="2">Option 2</option>
</select>
<select name="b">
<option value="1">Option 1</option>
<option value="2">Option 2</option>
</select>
<select name="c">
<option value="1">Option 1</option>
<option value="2">Option 2</option>
</select>
<input type="submit" value="continue">
</form>
提交表单时,第 2 页将是这样的
page2.php?a=1&b=5&c=20&d=30
<select name="a">
<option value="1" <?php echo($_GET['a']=='1')? 'selected': '';?>>Option 1</option>
<option value="2" <?php echo($_GET['a']=='2')? 'selected': '';?>>Option 2</option>
</select>
<select name="b">
<option value="1" <?php echo($_GET['b']=='1')? 'selected': '';?>>Option 1</option>
<option value="2" <?php echo($_GET['b']=='2')? 'selected': '';?>>Option 2</option>
</select>
<select name="c">
<option value="1" <?php echo($_GET['c']=='1')? 'selected': '';?>>Option 1</option>
<option value="2" <?php echo($_GET['a']=='2')? 'selected': '';?>>Option 2</option>
</select>
</form>
如何将此方法更改为 MVC 方法,例如:..../nameOfController/.......
NB: I know the basis of MVC.
我不认为你可以用原生的方式做到这一点,但你可以通过一些工作来完成这样的事情:
由于文件 "nameOfController" 不一定存在于您的应用程序中,因此您需要使用一些技巧,我将尽可能清楚地描述大多数 MVC 框架如何处理此类请求:
有一个 "main" 文件可以捕获每个请求并允许框架对其进行解释。例如,它在 Zend Framework 中称为 "index.php" 或在 Symfony 中称为 "app.php"。
带有一些规则的“.htaccess”文件会将您想要的每个请求重定向到您的主文件,以便您的主文件能够分析它们。您可以在这些规则中指定您不希望 Apache 将请求重定向到服务器上的真实资源(图像、css 文件等)
然后,有一个看起来像"router"/"dispatcher"的模块,它会根据请求的形状调用特定的控制器和特定的方法您决定的规则。
然后由您声明自己的规则以及您希望应用执行的操作(包含控制器的文件夹、控制器传统方法的名称等)
希望这对你有所帮助,抱歉我的英语不好
编辑:这是一个例子:
假设我们有一个 .htaccess 文件。我会特意以 Symfony 为例:
# Use the front controller as index file. It serves as a fallback solution when
# every other rewrite/redirect fails (e.g. in an aliased environment without
# mod_rewrite). Additionally, this reduces the matching process for the
# start page (path "/") because otherwise Apache will apply the rewriting rules
# to each configured DirectoryIndex file (e.g. index.php, index.html, index.pl).
DirectoryIndex app.php
# Disabling MultiViews prevents unwanted negotiation, e.g. "/app" should not resolve
# to the front controller "/app.php" but be rewritten to "/app.php/app".
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
<IfModule mod_rewrite.c>
RewriteEngine On
# Determine the RewriteBase automatically and set it as environment variable.
# If you are using Apache aliases to do mass virtual hosting or installed the
# project in a subdirectory, the base path will be prepended to allow proper
# resolution of the app.php file and to redirect to the correct URI. It will
# work in environments without path prefix as well, providing a safe, one-size
# fits all solution. But as you do not need it in this case, you can comment
# the following 2 lines to eliminate the overhead.
RewriteCond %{REQUEST_URI}:: ^(/.+)/(.*)::$
RewriteRule ^(.*) - [E=BASE:%1]
# Sets the HTTP_AUTHORIZATION header removed by apache
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect to URI without front controller to prevent duplicate content
# (with and without `/app.php`). Only do this redirect on the initial
# rewrite by Apache and not on subsequent cycles. Otherwise we would get an
# endless redirect loop (request -> rewrite to front controller ->
# redirect -> request -> ...).
# So in case you get a "too many redirects" error or you always get redirected
# to the start page because your Apache does not expose the REDIRECT_STATUS
# environment variable, you have 2 choices:
# - disable this feature by commenting the following 2 lines or
# - use Apache >= 2.3.9 and replace all L flags by END flags and remove the
# following RewriteCond (best solution)
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^app\.php(/(.*)|$) %{ENV:BASE}/ [R=301,L]
# If the requested filename exists, simply serve it.
# We only want to let Apache serve files and not directories.
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule .? - [L]
# Rewrite all other queries to the front controller.
RewriteRule .? %{ENV:BASE}/app.php [L]
</IfModule>
<IfModule !mod_rewrite.c>
<IfModule mod_alias.c>
# When mod_rewrite is not available, we instruct a temporary redirect of
# the start page to the front controller explicitly so that the website
# and the generated links can still be used.
RedirectMatch 302 ^/$ /app.php/
# RedirectTemp cannot be used instead
</IfModule>
</IfModule>
在全球范围内,此脚本确实将每个请求(指向物理现有资源的请求除外)重定向到名为 "app.php" 的文件上。此文件 "app.php" 旨在作为您的应用程序的启动器并包含以下代码:
<?php
use Symfony\Component\ClassLoader\ApcClassLoader;
use Symfony\Component\HttpFoundation\Request;
$loader = require_once __DIR__.'/../app/bootstrap.php.cache';
// Enable APC for autoloading to improve performance.
// You should change the ApcClassLoader first argument to a unique prefix
// in order to prevent cache key conflicts with other applications
// also using APC.
/*
$apcLoader = new ApcClassLoader(sha1(__FILE__), $loader);
$loader->unregister();
$apcLoader->register(true);
*/
require_once __DIR__.'/../app/AppKernel.php';
//require_once __DIR__.'/../app/AppCache.php';
$kernel = new AppKernel('prod', false);
$kernel->loadClassCache();
//$kernel = new AppCache($kernel);
// When using the HttpCache, you need to call the method in your front controller instead of relying on the configuration parameter
//Request::enableHttpMethodParameterOverride();
$request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);
这个加载内核(这是 Symfony 框架的代码)并尝试通过 PHP 全局变量重组请求:
$request = Request::createFromGlobals();
然后,内核处理我们的请求:
$response = $kernel->handle($request);
这会产生响应。
我们可以想象handle方法"analyses"请求方法(对应你的HTTP请求),会尝试推导出它要到达的controller,应该调用哪个方法。
在全球范围内,SF 应用程序及其模块(例如可以定义网站的不同部分)是这样设计的:有一个 "src" 文件夹,其中包含 "bundles"(模块)和这些包属于它们自己的命名空间,例如 Com\MyAppBundle\、Com\BlogBundle\、Com\AdminBundle\ 等
每个包都可以包含控制器(产生的命名空间:Com\MyAppBundle\Controller)、表单(Com\MyAppBundle\Form)等等,内核将尝试找到正确的资源来访问。它通常遵循 PSR-4 和 PSR-0 命名空间格式。
要了解特定类型的 URL 可以访问哪个控制器,Symfony 允许您定义 "routes" 将 URL 模式与特定规则相关联。
来自 Symfony 的路由示例(.yml 文件):
bloc_article_show:
pattern: /blog/article/{id}/
defaults: { _controller: "ComMyAppBundle:Blog:show" }
requirements:
id: \d+
这个名为 "bloc_article_show" 的规则是一个自定义规则,它表示 URL 匹配以下模式 /blog/article/{id}/(例如 /blog/article /9/),那么内核应该将请求分派给属于 Com\MyAppBundle\ 命名空间的名为 BlogController 的控制器。到达此控制器后,将调用方法 "show" 并将 $id 作为参数。我们还指定"id"参数必须是数字[0-9]+
警告:/bloc/article/ 不是现有的 directory/folder ;)
这是一个来自 Symfony 的直接示例,但大多数现有框架做的事情非常相似 :) 然后由您来定义 MVC 应用程序捕获请求并分派它们的方式。
希望这会有所帮助
我正在尝试借助 link uisng GET 方法中的值从数据库中检索一些数据...并使用自定义 php MVC..
由于我还是初学者,我不知道如何访问从第 1 页的表单发送到第 2 页的另一个表单的数据..
这是常规方式。
例子
page1.php
<form method="GET" action="<?php echo URL"./page2.".php ;?> ">
<select name="a">
<option value="1">Option 1</option>
<option value="2">Option 2</option>
</select>
<select name="b">
<option value="1">Option 1</option>
<option value="2">Option 2</option>
</select>
<select name="c">
<option value="1">Option 1</option>
<option value="2">Option 2</option>
</select>
<input type="submit" value="continue">
</form>
提交表单时,第 2 页将是这样的
page2.php?a=1&b=5&c=20&d=30
<select name="a">
<option value="1" <?php echo($_GET['a']=='1')? 'selected': '';?>>Option 1</option>
<option value="2" <?php echo($_GET['a']=='2')? 'selected': '';?>>Option 2</option>
</select>
<select name="b">
<option value="1" <?php echo($_GET['b']=='1')? 'selected': '';?>>Option 1</option>
<option value="2" <?php echo($_GET['b']=='2')? 'selected': '';?>>Option 2</option>
</select>
<select name="c">
<option value="1" <?php echo($_GET['c']=='1')? 'selected': '';?>>Option 1</option>
<option value="2" <?php echo($_GET['a']=='2')? 'selected': '';?>>Option 2</option>
</select>
</form>
如何将此方法更改为 MVC 方法,例如:..../nameOfController/.......
NB: I know the basis of MVC.
我不认为你可以用原生的方式做到这一点,但你可以通过一些工作来完成这样的事情:
由于文件 "nameOfController" 不一定存在于您的应用程序中,因此您需要使用一些技巧,我将尽可能清楚地描述大多数 MVC 框架如何处理此类请求:
有一个 "main" 文件可以捕获每个请求并允许框架对其进行解释。例如,它在 Zend Framework 中称为 "index.php" 或在 Symfony 中称为 "app.php"。
带有一些规则的“.htaccess”文件会将您想要的每个请求重定向到您的主文件,以便您的主文件能够分析它们。您可以在这些规则中指定您不希望 Apache 将请求重定向到服务器上的真实资源(图像、css 文件等)
然后,有一个看起来像"router"/"dispatcher"的模块,它会根据请求的形状调用特定的控制器和特定的方法您决定的规则。
然后由您声明自己的规则以及您希望应用执行的操作(包含控制器的文件夹、控制器传统方法的名称等)
希望这对你有所帮助,抱歉我的英语不好
编辑:这是一个例子:
假设我们有一个 .htaccess 文件。我会特意以 Symfony 为例:
# Use the front controller as index file. It serves as a fallback solution when
# every other rewrite/redirect fails (e.g. in an aliased environment without
# mod_rewrite). Additionally, this reduces the matching process for the
# start page (path "/") because otherwise Apache will apply the rewriting rules
# to each configured DirectoryIndex file (e.g. index.php, index.html, index.pl).
DirectoryIndex app.php
# Disabling MultiViews prevents unwanted negotiation, e.g. "/app" should not resolve
# to the front controller "/app.php" but be rewritten to "/app.php/app".
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
<IfModule mod_rewrite.c>
RewriteEngine On
# Determine the RewriteBase automatically and set it as environment variable.
# If you are using Apache aliases to do mass virtual hosting or installed the
# project in a subdirectory, the base path will be prepended to allow proper
# resolution of the app.php file and to redirect to the correct URI. It will
# work in environments without path prefix as well, providing a safe, one-size
# fits all solution. But as you do not need it in this case, you can comment
# the following 2 lines to eliminate the overhead.
RewriteCond %{REQUEST_URI}:: ^(/.+)/(.*)::$
RewriteRule ^(.*) - [E=BASE:%1]
# Sets the HTTP_AUTHORIZATION header removed by apache
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect to URI without front controller to prevent duplicate content
# (with and without `/app.php`). Only do this redirect on the initial
# rewrite by Apache and not on subsequent cycles. Otherwise we would get an
# endless redirect loop (request -> rewrite to front controller ->
# redirect -> request -> ...).
# So in case you get a "too many redirects" error or you always get redirected
# to the start page because your Apache does not expose the REDIRECT_STATUS
# environment variable, you have 2 choices:
# - disable this feature by commenting the following 2 lines or
# - use Apache >= 2.3.9 and replace all L flags by END flags and remove the
# following RewriteCond (best solution)
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^app\.php(/(.*)|$) %{ENV:BASE}/ [R=301,L]
# If the requested filename exists, simply serve it.
# We only want to let Apache serve files and not directories.
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule .? - [L]
# Rewrite all other queries to the front controller.
RewriteRule .? %{ENV:BASE}/app.php [L]
</IfModule>
<IfModule !mod_rewrite.c>
<IfModule mod_alias.c>
# When mod_rewrite is not available, we instruct a temporary redirect of
# the start page to the front controller explicitly so that the website
# and the generated links can still be used.
RedirectMatch 302 ^/$ /app.php/
# RedirectTemp cannot be used instead
</IfModule>
</IfModule>
在全球范围内,此脚本确实将每个请求(指向物理现有资源的请求除外)重定向到名为 "app.php" 的文件上。此文件 "app.php" 旨在作为您的应用程序的启动器并包含以下代码:
<?php
use Symfony\Component\ClassLoader\ApcClassLoader;
use Symfony\Component\HttpFoundation\Request;
$loader = require_once __DIR__.'/../app/bootstrap.php.cache';
// Enable APC for autoloading to improve performance.
// You should change the ApcClassLoader first argument to a unique prefix
// in order to prevent cache key conflicts with other applications
// also using APC.
/*
$apcLoader = new ApcClassLoader(sha1(__FILE__), $loader);
$loader->unregister();
$apcLoader->register(true);
*/
require_once __DIR__.'/../app/AppKernel.php';
//require_once __DIR__.'/../app/AppCache.php';
$kernel = new AppKernel('prod', false);
$kernel->loadClassCache();
//$kernel = new AppCache($kernel);
// When using the HttpCache, you need to call the method in your front controller instead of relying on the configuration parameter
//Request::enableHttpMethodParameterOverride();
$request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);
这个加载内核(这是 Symfony 框架的代码)并尝试通过 PHP 全局变量重组请求:
$request = Request::createFromGlobals();
然后,内核处理我们的请求:
$response = $kernel->handle($request);
这会产生响应。
我们可以想象handle方法"analyses"请求方法(对应你的HTTP请求),会尝试推导出它要到达的controller,应该调用哪个方法。
在全球范围内,SF 应用程序及其模块(例如可以定义网站的不同部分)是这样设计的:有一个 "src" 文件夹,其中包含 "bundles"(模块)和这些包属于它们自己的命名空间,例如 Com\MyAppBundle\、Com\BlogBundle\、Com\AdminBundle\ 等
每个包都可以包含控制器(产生的命名空间:Com\MyAppBundle\Controller)、表单(Com\MyAppBundle\Form)等等,内核将尝试找到正确的资源来访问。它通常遵循 PSR-4 和 PSR-0 命名空间格式。
要了解特定类型的 URL 可以访问哪个控制器,Symfony 允许您定义 "routes" 将 URL 模式与特定规则相关联。
来自 Symfony 的路由示例(.yml 文件):
bloc_article_show:
pattern: /blog/article/{id}/
defaults: { _controller: "ComMyAppBundle:Blog:show" }
requirements:
id: \d+
这个名为 "bloc_article_show" 的规则是一个自定义规则,它表示 URL 匹配以下模式 /blog/article/{id}/(例如 /blog/article /9/),那么内核应该将请求分派给属于 Com\MyAppBundle\ 命名空间的名为 BlogController 的控制器。到达此控制器后,将调用方法 "show" 并将 $id 作为参数。我们还指定"id"参数必须是数字[0-9]+
警告:/bloc/article/ 不是现有的 directory/folder ;)
这是一个来自 Symfony 的直接示例,但大多数现有框架做的事情非常相似 :) 然后由您来定义 MVC 应用程序捕获请求并分派它们的方式。
希望这会有所帮助