由于 htaccess,PDOCrud + 路由库不能一起工作,为什么?
PDOCrud + Routing libraries don't work together due to htaccess, why?
我正在使用这个 library for all my CRUD operations, as well as this 进行路由。
当我尝试“添加、编辑或删除”时,我得到 404 not found
经过四处调查,我发现问题出在 .htaccess
文件上。
RewriteEngine On
RewriteCond %{REQUEST_URI} !(\.png|\.jpg|\.gif|\.jpeg|\.zip|\.css|\.svg|\.js)$
RewriteRule (.*) routes.php [QSA,L]
# BEGIN Pdocrud
<IfModule mod_rewrite.c>
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)$ .php
</IfModule>
<IfModule mod_expires.c>
# Enable expirations
ExpiresActive On
# HTML
ExpiresByType text/html "access plus 2 days"
</IfModule>
# END Pdocrud
前3行负责路由。当我删除它们时 PDOCrud 工作,但是我的 url 将是 localhost/public/view/reports.view.php
而不是 localhost/cases-reports
.
如何重构 .htaccess
使其正常工作?
PDOCrudAjaxCtrl.php
<?php
@session_start();
Class PDOCrudAjaxCtrl {
public function handleRequest() {
$instanceKey = $_REQUEST["pdocrud_instance"];
if(!isset($_SESSION["pdocrud_sess"][$instanceKey])){
die("Session has been expired. Please refresh your page to continue.");
}
$pdocrud = unserialize($_SESSION["pdocrud_sess"][$instanceKey]);
$action = $_POST["pdocrud_data"]["action"];
$data = $_POST["pdocrud_data"];
$post = $_POST;
if (isset($_FILES))
$post = array_merge($_FILES, $post);
$data["post"] = $post;
switch (strtoupper($action)) {
case "VIEW":
echo $pdocrud->render("VIEWFORM", $data);
break;
case "SORT":
$pdocrud->setBackOperation();
$data["action"] = "asc";
echo $pdocrud->render("CRUD", $data);
break;
case "ASC":
$pdocrud->setBackOperation();
echo $pdocrud->render("CRUD", $data);
break;
case "DESC":
$pdocrud->setBackOperation();
echo $pdocrud->render("CRUD", $data);
break;
case "ADD":
echo $pdocrud->render("INSERTFORM", $data);
break;
case "INSERT":
$pdocrud->render("INSERT", $post);
break;
case "INSERT_CLOSE":
$pdocrud->setBackOperation();
$pdocrud->render("INSERT", $post);
break;
case "INSERT_BACK":
$pdocrud->setBackOperation();
$pdocrud->render("INSERT", $post);
$pdocrud->setBackOperation();
echo $pdocrud->render("CRUD", $data);
break;
case "BACK":
$pdocrud->setBackOperation();
echo $pdocrud->render("CRUD", $data);
break;
case "EDIT":
$pdocrud->setInlineEdit(false);
echo $pdocrud->render("EDITFORM", $data);
break;
case "INLINE_EDIT":
$pdocrud->setBackOperation();
$pdocrud->setInlineEdit(true);
echo $pdocrud->render("EDITFORM", $data);
break;
case "ONEPAGEEDIT":
$pdocrud->setBackOperation();
$pdocrud->setInlineEdit(false);
echo $pdocrud->render("ONEPAGE", $data);
break;
case "ONEPAGEVIEW":
$pdocrud->setBackOperation();
echo $pdocrud->render("ONEPAGE", $data);
break;
case "QUICK_VIEW":
echo $pdocrud->render("QUICKVIEW", $data);
break;
case "RELATED_TABLE":
echo $pdocrud->render("RELATED_TABLE", $data);
break;
case "INLINE_BACK":
$pdocrud->render("UPDATE", $post);
echo $pdocrud->render("CRUD", $data);
break;
case "UPDATE":
$pdocrud->render("UPDATE", $post);
break;
case "UPDATE_BACK":
$pdocrud->setBackOperation();
$pdocrud->render("UPDATE", $post);
$pdocrud->setBackOperation();
echo $pdocrud->render("CRUD", $data);
break;
case "UPDATE_CLOSE":
$pdocrud->setBackOperation();
$pdocrud->render("UPDATE", $post);
break;
case "DELETE":
$pdocrud->render("DELETE", $data);
$pdocrud->setBackOperation();
echo $pdocrud->render("CRUD", $data);
break;
case "DELETE_SELECTED":
$pdocrud->render("DELETE_SELECTED", $data);
$pdocrud->setBackOperation();
echo $pdocrud->render("CRUD", $data);
break;
case "PAGINATION":
$pdocrud->setBackOperation();
$pdocrud->currentPage($data["page"]);
echo $pdocrud->render("CRUD", $data);
break;
case "RECORDS_PER_PAGE":
$pdocrud->currentPage(1);
$pdocrud->recordsPerPage($data["records"]);
echo $pdocrud->render("CRUD", $data);
break;
case "SEARCH":
$pdocrud->currentPage(1);
echo $pdocrud->render("CRUD", $data);
break;
case "AUTOSUGGEST":
if(isset($_GET["callback"]))
$data["callback"] = $_GET["callback"];
echo $pdocrud->render("AUTOSUGGEST", $data);
break;
case "EXPORTTABLE":
echo $pdocrud->render("EXPORTTABLE", $data);
break;
case "EXPORTFORM":
$pdocrud->render("EXPORTFORM", $data);
break;
case "SWITCH":
$pdocrud->setBackOperation();
$pdocrud->render("SWITCH", $data);
echo $pdocrud->render("CRUD", $data);
break;
case "BTNSWITCH":
$pdocrud->setBackOperation();
$pdocrud->render("BTNSWITCH", $data);
echo $pdocrud->render("CRUD", $data);
break;
case "LOADDEPENDENT":
echo $pdocrud->render("LOADDEPENDENT", $data);
break;
case "EMAIL" : echo $pdocrud->render("EMAIL", $post);
break;
case "SELECT":
$pdocrud->setBackOperation();
echo $pdocrud->render("CRUD", $data);
break;
case "SELECTFORM":
echo $pdocrud->render("SELECT", $post);
break;
case "FILTER":
$pdocrud->setBackOperation();
$pdocrud->currentPage(1);
echo $pdocrud->render("CRUD", $data);
break;
case "RELOAD":
$pdocrud->setBackOperation();
echo $pdocrud->render("CRUD", $data);
break;
case "SAVE_CRUD_TABLE_DATA":
$pdocrud->setBackOperation();
$pdocrud->render("SAVE_CRUD_DATA", $data);
echo $pdocrud->render("CRUD", $data);
break;
case "RENDER_ADV_SEARCH":
$pdocrud->currentPage(1);
echo $pdocrud->render("CRUD", $data);
break;
case "DATE_RANGE_REPORT":
$pdocrud->setBackOperation();
$pdocrud->currentPage(1);
echo $pdocrud->render("CRUD", $data);
break;
case "CLONE":
echo $pdocrud->render("CLONEFORM", $data);
break;
case "CELL_UPDATE":
$updateData[$data["column"]] = $data["content"];
if (isset($data["id"]))
$pdocrud->setPrimarykeyValue($data["id"]);
$pdocrud->render("UPDATE", $updateData);
break;
case "AJAX_ACTION":
echo $pdocrud->render("AJAX_ACTION", $data);
break;
case "PRINTPDF":
echo $pdocrud->render("PRINT_PDF", $data);
break;
default:
break;
}
}
}
RewriteCond %{REQUEST_URI} !(\.png|\.jpg|\.gif|\.jpeg|\.zip|\.css|\.svg|\.js)$
RewriteRule (.*) routes.php [QSA,L]
# BEGIN Pdocrud
<IfModule mod_rewrite.c>
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)$ .php
</IfModule>
第一条规则将所有内容重写为 routes.php
,因此甚至不处理第二条规则。您需要颠倒这两条规则才能使它有意义。但是,应该注意的是,这两个系统的存在似乎对可以作为“路由”实现的 URL 类型强加了“无声”限制。
然而,第二条规则无论如何都不是严格正确的,因为它可能重写为与前面 条件 中测试的不同的 URL(这可能对于某些请求,可能会导致重写循环,即 500 错误。有关此的更多详细信息,请参阅 the following question on ServerFault。
改为尝试以下操作(假设 .htaccess
文件位于文档根目录中):
RewriteEngine On
# BEGIN Pdocrud
RewriteCond %{REQUEST_URI} !\.(php|png|jpe?g|gif|zip|css|svg|js)$
RewriteCond %{DOCUMENT_ROOT}/.php -f
RewriteRule (.*) .php [L]
<IfModule mod_expires.c>
# Enable expirations
ExpiresActive On
# HTML
ExpiresByType text/html "access plus 2 days"
</IfModule>
# END Pdocrud
RewriteRule !\.(png|jpg|gif|jpeg|zip|css|svg|js)$ routes.php [L]
补充说明:
在附加 .php
扩展名的“Pdocrud”规则中,没有必要检查请求是否映射到目录,然后再检查它是否映射到文件。
在您的“路由”规则中,不需要前面的条件 - 此检查应该在 RewriteRule
中执行。同样,不需要 QSA
标志。
此配置的一个限制是您不能拥有恰好映射到 .php
文件的“路由”(当附加 .php
时)。
我正在使用这个 library for all my CRUD operations, as well as this 进行路由。
当我尝试“添加、编辑或删除”时,我得到 404 not found
经过四处调查,我发现问题出在 .htaccess
文件上。
RewriteEngine On
RewriteCond %{REQUEST_URI} !(\.png|\.jpg|\.gif|\.jpeg|\.zip|\.css|\.svg|\.js)$
RewriteRule (.*) routes.php [QSA,L]
# BEGIN Pdocrud
<IfModule mod_rewrite.c>
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)$ .php
</IfModule>
<IfModule mod_expires.c>
# Enable expirations
ExpiresActive On
# HTML
ExpiresByType text/html "access plus 2 days"
</IfModule>
# END Pdocrud
前3行负责路由。当我删除它们时 PDOCrud 工作,但是我的 url 将是 localhost/public/view/reports.view.php
而不是 localhost/cases-reports
.
如何重构 .htaccess
使其正常工作?
PDOCrudAjaxCtrl.php
<?php
@session_start();
Class PDOCrudAjaxCtrl {
public function handleRequest() {
$instanceKey = $_REQUEST["pdocrud_instance"];
if(!isset($_SESSION["pdocrud_sess"][$instanceKey])){
die("Session has been expired. Please refresh your page to continue.");
}
$pdocrud = unserialize($_SESSION["pdocrud_sess"][$instanceKey]);
$action = $_POST["pdocrud_data"]["action"];
$data = $_POST["pdocrud_data"];
$post = $_POST;
if (isset($_FILES))
$post = array_merge($_FILES, $post);
$data["post"] = $post;
switch (strtoupper($action)) {
case "VIEW":
echo $pdocrud->render("VIEWFORM", $data);
break;
case "SORT":
$pdocrud->setBackOperation();
$data["action"] = "asc";
echo $pdocrud->render("CRUD", $data);
break;
case "ASC":
$pdocrud->setBackOperation();
echo $pdocrud->render("CRUD", $data);
break;
case "DESC":
$pdocrud->setBackOperation();
echo $pdocrud->render("CRUD", $data);
break;
case "ADD":
echo $pdocrud->render("INSERTFORM", $data);
break;
case "INSERT":
$pdocrud->render("INSERT", $post);
break;
case "INSERT_CLOSE":
$pdocrud->setBackOperation();
$pdocrud->render("INSERT", $post);
break;
case "INSERT_BACK":
$pdocrud->setBackOperation();
$pdocrud->render("INSERT", $post);
$pdocrud->setBackOperation();
echo $pdocrud->render("CRUD", $data);
break;
case "BACK":
$pdocrud->setBackOperation();
echo $pdocrud->render("CRUD", $data);
break;
case "EDIT":
$pdocrud->setInlineEdit(false);
echo $pdocrud->render("EDITFORM", $data);
break;
case "INLINE_EDIT":
$pdocrud->setBackOperation();
$pdocrud->setInlineEdit(true);
echo $pdocrud->render("EDITFORM", $data);
break;
case "ONEPAGEEDIT":
$pdocrud->setBackOperation();
$pdocrud->setInlineEdit(false);
echo $pdocrud->render("ONEPAGE", $data);
break;
case "ONEPAGEVIEW":
$pdocrud->setBackOperation();
echo $pdocrud->render("ONEPAGE", $data);
break;
case "QUICK_VIEW":
echo $pdocrud->render("QUICKVIEW", $data);
break;
case "RELATED_TABLE":
echo $pdocrud->render("RELATED_TABLE", $data);
break;
case "INLINE_BACK":
$pdocrud->render("UPDATE", $post);
echo $pdocrud->render("CRUD", $data);
break;
case "UPDATE":
$pdocrud->render("UPDATE", $post);
break;
case "UPDATE_BACK":
$pdocrud->setBackOperation();
$pdocrud->render("UPDATE", $post);
$pdocrud->setBackOperation();
echo $pdocrud->render("CRUD", $data);
break;
case "UPDATE_CLOSE":
$pdocrud->setBackOperation();
$pdocrud->render("UPDATE", $post);
break;
case "DELETE":
$pdocrud->render("DELETE", $data);
$pdocrud->setBackOperation();
echo $pdocrud->render("CRUD", $data);
break;
case "DELETE_SELECTED":
$pdocrud->render("DELETE_SELECTED", $data);
$pdocrud->setBackOperation();
echo $pdocrud->render("CRUD", $data);
break;
case "PAGINATION":
$pdocrud->setBackOperation();
$pdocrud->currentPage($data["page"]);
echo $pdocrud->render("CRUD", $data);
break;
case "RECORDS_PER_PAGE":
$pdocrud->currentPage(1);
$pdocrud->recordsPerPage($data["records"]);
echo $pdocrud->render("CRUD", $data);
break;
case "SEARCH":
$pdocrud->currentPage(1);
echo $pdocrud->render("CRUD", $data);
break;
case "AUTOSUGGEST":
if(isset($_GET["callback"]))
$data["callback"] = $_GET["callback"];
echo $pdocrud->render("AUTOSUGGEST", $data);
break;
case "EXPORTTABLE":
echo $pdocrud->render("EXPORTTABLE", $data);
break;
case "EXPORTFORM":
$pdocrud->render("EXPORTFORM", $data);
break;
case "SWITCH":
$pdocrud->setBackOperation();
$pdocrud->render("SWITCH", $data);
echo $pdocrud->render("CRUD", $data);
break;
case "BTNSWITCH":
$pdocrud->setBackOperation();
$pdocrud->render("BTNSWITCH", $data);
echo $pdocrud->render("CRUD", $data);
break;
case "LOADDEPENDENT":
echo $pdocrud->render("LOADDEPENDENT", $data);
break;
case "EMAIL" : echo $pdocrud->render("EMAIL", $post);
break;
case "SELECT":
$pdocrud->setBackOperation();
echo $pdocrud->render("CRUD", $data);
break;
case "SELECTFORM":
echo $pdocrud->render("SELECT", $post);
break;
case "FILTER":
$pdocrud->setBackOperation();
$pdocrud->currentPage(1);
echo $pdocrud->render("CRUD", $data);
break;
case "RELOAD":
$pdocrud->setBackOperation();
echo $pdocrud->render("CRUD", $data);
break;
case "SAVE_CRUD_TABLE_DATA":
$pdocrud->setBackOperation();
$pdocrud->render("SAVE_CRUD_DATA", $data);
echo $pdocrud->render("CRUD", $data);
break;
case "RENDER_ADV_SEARCH":
$pdocrud->currentPage(1);
echo $pdocrud->render("CRUD", $data);
break;
case "DATE_RANGE_REPORT":
$pdocrud->setBackOperation();
$pdocrud->currentPage(1);
echo $pdocrud->render("CRUD", $data);
break;
case "CLONE":
echo $pdocrud->render("CLONEFORM", $data);
break;
case "CELL_UPDATE":
$updateData[$data["column"]] = $data["content"];
if (isset($data["id"]))
$pdocrud->setPrimarykeyValue($data["id"]);
$pdocrud->render("UPDATE", $updateData);
break;
case "AJAX_ACTION":
echo $pdocrud->render("AJAX_ACTION", $data);
break;
case "PRINTPDF":
echo $pdocrud->render("PRINT_PDF", $data);
break;
default:
break;
}
}
}
RewriteCond %{REQUEST_URI} !(\.png|\.jpg|\.gif|\.jpeg|\.zip|\.css|\.svg|\.js)$ RewriteRule (.*) routes.php [QSA,L] # BEGIN Pdocrud <IfModule mod_rewrite.c> RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME}.php -f RewriteRule ^(.*)$ .php </IfModule>
第一条规则将所有内容重写为 routes.php
,因此甚至不处理第二条规则。您需要颠倒这两条规则才能使它有意义。但是,应该注意的是,这两个系统的存在似乎对可以作为“路由”实现的 URL 类型强加了“无声”限制。
然而,第二条规则无论如何都不是严格正确的,因为它可能重写为与前面 条件 中测试的不同的 URL(这可能对于某些请求,可能会导致重写循环,即 500 错误。有关此的更多详细信息,请参阅 the following question on ServerFault。
改为尝试以下操作(假设 .htaccess
文件位于文档根目录中):
RewriteEngine On
# BEGIN Pdocrud
RewriteCond %{REQUEST_URI} !\.(php|png|jpe?g|gif|zip|css|svg|js)$
RewriteCond %{DOCUMENT_ROOT}/.php -f
RewriteRule (.*) .php [L]
<IfModule mod_expires.c>
# Enable expirations
ExpiresActive On
# HTML
ExpiresByType text/html "access plus 2 days"
</IfModule>
# END Pdocrud
RewriteRule !\.(png|jpg|gif|jpeg|zip|css|svg|js)$ routes.php [L]
补充说明:
在附加
.php
扩展名的“Pdocrud”规则中,没有必要检查请求是否映射到目录,然后再检查它是否映射到文件。在您的“路由”规则中,不需要前面的条件 - 此检查应该在
RewriteRule
中执行。同样,不需要QSA
标志。此配置的一个限制是您不能拥有恰好映射到
.php
文件的“路由”(当附加.php
时)。