slim框架中pjax的实现
pjax = pushState + ajax
由于这是一个比较通用的组件,所以我把它写成了slim的Middleware (如果不知道middleware是什么或者怎么写,可以看这里)
大概原理是在slim框架渲染之后,输出之前,对dom结构进行分析,摘取出pjax所需要的部分,然后将这部分的内容作为response返回给浏览器的ajax请求
预览: 码农文库 点击分页可以看到效果
$app->add(new \Support\PjaxMiddleware());
<?php
namespace Support;
use Slim\Middleware;
use Slim\Http\Request;
use Slim\Http\Response;
use Symfony\Component\DomCrawler\Crawler;
class PjaxMiddleware extends Middleware
{
public function call()
{
$request = $this->app->request();
$response = $this->app->response();
$this->next->call();
if (!$request->headers('X-PJAX') || $response->isRedirect()) {
return;
}
$this->filterResponse($response, $request->headers('X-PJAX-CONTAINER'))->setUriHeader($response, $request);
}
private function filterResponse(Response $response, $container)
{
$crawler = new Crawler($response->getBody());
$response->setBody($this->makeTitle($crawler) . $this->fetchContents($crawler, $container));
return $this;
}
private function makeTitle(Crawler $crawler)
{
$title = $crawler->filter('head > title')->html();
return "<title>{$title}</title>";
}
private function fetchContents(Crawler $crawler, $container)
{
$content = $crawler->filter($container);
if (!$content->count()) {
$this->app->stop();
}
return $content->html();
}
private function setUriHeader(Response $response, Request $request)
{
$query = $request->get();
unset($query['_pjax']);
$response->header('X-PJAX-URL', $request->getResourceUri() . '?' . http_build_query($query));
}
}