教科书般的PHP框架学习指南php
注:翻译水平有限,若有错误,欢迎指正html
Slim is a PHP micro framework that helps you quickly write simple yet powerful web applications and APIs. At its core, Slim is a dispatcher that receives an HTTP request, invokes an appropriate callback routine, and returns an HTTP response. That’s it.前端
Slim是一个PHP微框架,能够帮助您快速编写简单但功能强大的web应用程序和api。Slim的核心是一个dispatcher(调度器),它接收HTTP请求,调用适当的回调例程,并返回HTTP响应。就是这样。web
Slim is an ideal tool to create APIs that consume, repurpose, or publish data. Slim is also a great tool for rapid prototyping. Heck, you can even build full-featured web applications with user interfaces. More importantly, Slim is super fast and has very little code. In fact, you can read and understand its source code in only an afternoon!api
Slim是消费、重用或发布数据的理想API工具。Slim也是快速原型制做的一个很好的工具。见鬼,您甚至可使用用户界面构建功能齐全的web应用程序。更重要的是,Slim速度很是快,代码不多。事实上,您只需一个下午就能够阅读和理解它的源代码!缓存
You don’t always need a kitchen-sink solution like Symfony or Laravel. These are great tools, for sure. But they are often overkill. Instead, Slim provides only a minimal set of tools that do what you need and nothing else.bash
你并不老是须要像Symfony或Laravel那么激进的解决方案。毫无疑问,这些都是很棒的工具。但它们每每是矫枉过正。相反,Slim只提供了一组最小的工具,它们只作您须要的事情,而不作其余任何事情。服务器
First, you need a web server like Nginx or Apache. You should configure your web server so that it sends all appropriate requests to one “front-controller” PHP file. You instantiate and run your Slim app in this PHP file.cookie
A Slim app contains routes that respond to specific HTTP requests. Each route invokes a callback and returns an HTTP response. To get started, you first instantiate and configure the Slim application. Next, you define your application routes. Finally, you run the Slim application. It’s that easy. Here’s an example application:app
首先,您须要像Nginx或Apache这样的web服务器。您应该配置您的web服务器,以便它将全部适当的请求发送到一个“前端控制器”PHP文件。在这个PHP文件中实例化并运行Slim应用程序。
slim应用程序包含响应特定HTTP请求的路由。每一个路由调用一个回调并返回一个HTTP响应。首先,您要实例化并配置Slim应用程序。接下来,定义应用程序路由。最后,运行Slim应用程序。它是那么容易。下面是一个应用程序示例:
<?php
// Create and configure Slim app
$config = ['settings' => [
'addContentLengthHeader' => false,
]];
$app = new \Slim\App($config);
// Define app routes
$app->get('/hello/{name}', function ($request, $response, $args) {
return $response->write("Hello " . $args['name']);
});
// Run app
$app->run();
复制代码
When you build a Slim app, you are often working directly with Request and Response objects. These objects represent the actual HTTP request received by the web server and the eventual HTTP response returned to the client.
Every Slim app route is given the current Request and Response objects as arguments to its callback routine. These objects implement the popular PSR 7 interfaces. The Slim app route can inspect or manipulate these objects as necessary. Ultimately, each Slim app route MUST return a PSR 7 Response object.
当您构建一个Slim应用程序时,您常常直接处理请求和响应对象。这些对象表示web服务器接收到的实际HTTP请求和返回给客户机的最终HTTP响应。
每一个Slim应用程序路由都将当前请求和响应对象做为其回调例程的参数。这些对象实现了流行的PSR 7接口。Slim应用程序路由能够根据须要检查或操做这些对象。最终,每一个Slim应用程序路由必须返回一个PSR 7响应对象。
Slim is designed to play well with other PHP components, too. You can register additional first-party components such as Slim-Csrf, Slim-HttpCache, or Slim-Flash that build upon Slim’s default functionality. It’s also easy to integrate third-party components found on Packagist.
Slim还能够很好地与其余PHP组件配合使用。您能够额外注册基于Slim默认功能的自有组件,如Slim-csrf、Slim-httpcache或Slim-flash。或者集成Packagist上的第三方组件也很容易。
If you are new to Slim, I recommend you read this documentation from start to finish. If you are already familiar with Slim, you can instead jump straight to the appropriate section.
若是您是Slim的新手,我建议您从头至尾阅读本文。若是您已经熟悉Slim,则能够直接跳到相应的部分。
This documentation begins by explaining Slim’s concepts and architecture before venturing into specific topics like request and response handling, routing, and error handling.
本文档首先解释Slim的概念和体系结构,而后讨论请求和响应处理、路由和错误处理等特定主题。
Web server with URL rewriting
PHP 5.5 or newer
复制代码
We recommend you install Slim with Composer. Navigate into your project’s root directory and execute the bash command shown below. This command downloads the Slim Framework and its third-party dependencies into your project’s vendor/ directory.
咱们建议您使用Composer安装Slim。导航到项目的根目录并执行以下所示的bash命令。此命令将Slim框架及其第三方依赖项下载到项目的vendor/目录中。
composer require slim/slim "^3.0"
复制代码
Require the Composer autoloader into your PHP script, and you are ready to start using Slim.
<?php
require 'vendor/autoload.php';
复制代码
New PHP version
Slim 3 requires PHP 5.5+
复制代码
Slim 3 uses \Slim\App for the Application object usually named $app.
$app = new \Slim\App();
复制代码
$app->get('/', function (Request $req, Response $res, $args = []) {
return $res->withStatus(400)->write('Bad Request');
});
复制代码
As mentioned above, Slim 3 passes the Request and Response objects as arguments to the route handling function. Since they are now accessible directly in the body of a route function, request and response are no longer properties of the /Slim/App (Application object) instance.
如上所述,Slim 3将请求和响应对象做为参数传递给路由处理函数。因为它们如今能够在route函数体中直接访问,请求和响应再也不是/Slim/App(应用程序对象)实例的属性。
$app->get('/', function (Request $req, Response $res, $args = []) {
$myvar1 = $req->getParam('myvar'); //checks both _GET and _POST [NOT PSR-7 Compliant]
$myvar2 = $req->getParsedBody()['myvar']; //checks _POST [IS PSR-7 compliant]
$myvar3 = $req->getQueryParams()['myvar']; //checks _GET [IS PSR-7 compliant]
});
复制代码
Hooks are no longer part of Slim as of v3. You should consider reimplementing any functionality associated with the default hooks in Slim v2 as middleware instead. If you need the ability to apply custom hooks at arbitrary points in your code (for example, within a route), you should consider a third-party package such as Symfony’s EventDispatcher or Zend Framework’s EventManager.
钩子在v3中再也不是Slim的一部分。您应该考虑将Slim v2中与缺省钩子相关的任何功能从新实现为中间件。若是您须要在代码中的任意点应用自定义钩子的能力(例如,在路由中),您应该考虑第三方包,如Symfony的EventDispatcher或Zend Framework的EventManager。
In Slim v3 we have removed the HTTP-Caching into its own module Slim\Http\Cache.
在Slim v3中,咱们已经将Http缓存迁移到它本身的模块Slim\Http\Cache中。
Slim Core has removed Stop/Halt. In your applications, you should transition to using the withStatus() and withBody() methods.
Slim内核已删除Stop/Halt。在应用程序中,应该过渡到使用withStatus()和withBody()方法。
为何有些框架愈来愈复杂,由于里面充斥着过期的代码,混淆了开发者,及时清理很重要,保持简单,避免出现重复的轮子
Slim::registerAutoloader() have been removed, we have fully moved to composer.
Slim: registerAutoloader()已被删除,咱们已经彻底迁移到composer。
$app->container->singleton(...) is now $container = $app->getContainer();
$container['...'] = function () {};
Please read Pimple docs for more info
复制代码
$app->configureMode(...) has been removed in v3.
PrettyExceptions cause lots of issues for many people, so these have been removed. 漂亮的异常会给不少人带来不少问题,因此这些已经被删除了。
We have switched routers which enable you to keep the default conditions regex inside of the route pattern.
In Slim v2.x one would use the helper function $app->redirect(); to trigger a redirect request. In Slim v3.x one can do the same with using the Response class like so.
在Slim v2.x 使用助手函数$app->redirect();触发重定向请求。在Slim v3.x 使用Response类也能够这样作。
Example:
$app->get('/', function ($req, $res, $args) {
return $res->withStatus(302)->withHeader('Location', 'your-new-uri');
});
Alternatively, if you want a route to redirect without any other handling, you can use the shortcut helper function $app->redirect() as the route definition:
$app->redirect('/', 'your-new-uri');
复制代码
The middleware signature has changed from a class to a function.
中间件特性已从类更改成函数。
New signature:
use Psr\Http\Message\RequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
$app->add(function (Request $req, Response $res, callable $next) {
// Do stuff before passing along
$newResponse = $next($req, $res);
// Do stuff after route is rendered
return $newResponse; // continue
});
复制代码
You can still use a class:
namespace My;
use Psr\Http\Message\RequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
class Middleware
{
function __invoke(Request $req, Response $res, callable $next) {
// Do stuff before passing along
$newResponse = $next($req, $res);
// Do stuff after route is rendered
return $newResponse; // continue
}
}
// Register
$app->add(new My\Middleware());
// or
$app->add(My\Middleware::class);
复制代码
Application middleware is executed as Last In First Executed (LIFE).
应用程序首次被执行时,中间件被放在了最后执行
Flash messages are no longer a part of the Slim v3 core but instead have been moved to seperate Slim Flash package.
Flash消息再也不是Slim v3核心的一部分,而是被迁移成了独立的Slim Flash包。
In v3.0 cookies has been removed from core. See FIG Cookies for a PSR-7 compatible cookie component.
在v3.0中cookies已经从核心中移除。参见FIG Cookies了解PSR-7兼容的cookie组件。
In v3.0 we have removed the dependency for crypto in core.
在v3.0中,咱们已经消除了Crypto的依赖。
Slim now utilizes FastRoute, a new, more powerful router!
This means that the specification of route patterns has changed with named parameters now in braces and square brackets used for optional segments:
Slim如今利用FastRoute,一个新的,更强大的路由器!
这意味着路由模式的规范已经发生了变化,命名参数如今在大括号和方括号中用于可选段:
// named parameter:
$app->get('/hello/{name}', /*...*/);
// optional segment:
$app->get('/news[/{year}]', /*...*/);
复制代码
The syntax for adding route middleware has changed slightly. In v3.0:
添加路由中间件的语法略有变化。在v3.0:
$app->get(…)->add($mw2)->add($mw1);
复制代码
The route is an attribute of the Request object in v3.0:
路由是v3.0中请求对象的一个属性:
$request->getAttribute('route');
复制代码
When getting the current route in middleware, the value for determineRouteBeforeAppMiddleware must be set to true in the Application configuration, otherwise the getAttribute call returns null.
当在中间件中获取当前路由时,应用程序配置中必须将defineroutebeforeappmiddleware的值设置为true,不然getAttribute调用将返回null。
urlFor() has been renamed pathFor() and can be found in the router object:
urlFor()被重命名为pathFor(),能够在router对象中找到:
$app->get('/', function ($request, $response, $args) {
$url = $this->router->pathFor('home');
$response->write("<a href='$url'>Home</a>");
return $response;
})->setName('home');
复制代码
Also, pathFor() is base path aware.
此外,pathFor()是基本路径感知的。
Slim uses Pimple as a Dependency Injection Container.
Slim使用Pimple做为依赖注入容器。
// index.php
$app = new Slim\App(
new \Slim\Container(
include '../config/container.config.php'
)
);
// Slim will grab the Home class from the container defined below and execute its index method.
// If the class is not defined in the container Slim will still contruct it and pass the container as the first arugment to the constructor!
$app->get('/', Home::class . ':index');
// In container.config.php
// We are using the SlimTwig here
return [
'settings' => [
'viewTemplatesDirectory' => '../templates',
],
'twig' => [
'title' => '',
'description' => '',
'author' => ''
],
'view' => function ($c) {
$view = new Twig(
$c['settings']['viewTemplatesDirectory'],
[
'cache' => false // '../cache'
]
);
// Instantiate and add Slim specific extension
$view->addExtension(
new TwigExtension(
$c['router'],
$c['request']->getUri()
)
);
foreach ($c['twig'] as $name => $value) {
$view->getEnvironment()->addGlobal($name, $value);
}
return $view;
},
Home::class => function ($c) {
return new Home($c['view']);
}
];
复制代码
Request, Response, Uri & UploadFile are immutable. This means that when you change one of these objects, the old instance is not updated.
请求、响应、Uri和UploadFile是不可变的。 这意味着当您更改其中一个对象时,旧实例不会更新。
// This is WRONG. The change will not pass through.
$app->add(function (Request $request, Response $response, $next) {
$request->withAttribute('abc', 'def');
return $next($request, $response);
});
// This is correct.
$app->add(function (Request $request, Response $response, $next) {
$request = $request->withAttribute('abc', 'def');
return $next($request, $response);
});
复制代码
// ...
$image = __DIR__ . '/huge_photo.jpg';
$body = new Stream($image);
$response = (new Response())
->withStatus(200, 'OK')
->withHeader('Content-Type', 'image/jpeg')
->withHeader('Content-Length', filesize($image))
->withBody($body);
// ...
复制代码
For text:
// ...
$response = (new Response())->getBody()->write('Hello world!')
// Or Slim specific: Not PSR-7 compliant.
$response = (new Response())->write('Hello world!');
// ...
复制代码
It is typical to use the front-controller pattern to funnel appropriate HTTP requests received by your web server to a single PHP file. The instructions below explain how to tell your web server to send HTTP requests to your PHP front-controller file.
一般使用前端控制器模式将web服务器接收到的适当HTTP请求引导到单个PHP文件。下面的说明说明了如何告诉web服务器将HTTP请求发送到PHP前端控制器文件。
Run the following command in terminal to start localhost web server, assuming ./public/ is public-accessible directory with index.php file:
假设./public/是带有index.php文件的公共可访问目录,在终端中运行如下命令启动localhost web服务器:
php -S localhost:8888 -t public public/index.php
复制代码
If you are not using index.php as your entry point then change appropriately.
若是您没有使用index.php做为入口点,那么请进行适当的更改。
Ensure your .htaccess and index.php files are in the same public-accessible directory. The .htaccess file should contain this code:
确保.htaccess和index.php文件位于同一个公共访问目录中。.htaccess文件应该包含如下代码:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [QSA,L]
复制代码
This .htaccess file requires URL rewriting. Make sure to enable Apache’s mod_rewrite module and your virtual host is configured with the AllowOverride option so that the .htaccess rewrite rules can be used:
这个.htaccess文件须要URL重写。请确保启用Apache的mod_rewrite模块,而且您的虚拟主机配置了AllowOverride选项,以即可以使用.htaccess重写规则:
AllowOverride All
复制代码
This is an example Nginx virtual host configuration for the domain example.com. It listens for inbound HTTP connections on port 80. It assumes a PHP-FPM server is running on port 9000. You should update the server_name, error_log, access_log, and root directives with your own values. The root directive is the path to your application’s public document root directory; your Slim app’s index.php front-controller file should be in this directory.
这是一个为example.com配置的Nginx虚拟主机配置示例。它侦听端口80上的入站HTTP链接。它假设PHP-FPM服务器运行在端口9000上。您应该使用本身的值更新server_name、error_log、access_log和根指令。根指令是应用程序的公共文档根目录的路径;Slim应用程序的index.php前端控制器文件应该在这个目录中。
server {
listen 80;
server_name example.com;
index index.php;
error_log /path/to/example.error.log;
access_log /path/to/example.access.log;
root /path/to/public;
location / {
try_files $uri /index.php$is_args$args;
}
location ~ \.php {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_index index.php;
fastcgi_pass 127.0.0.1:9000;
}
}
复制代码
Your HipHop Virtual Machine configuration file should contain this code (along with other settings you may need). Be sure you change the SourceRoot setting to point to your Slim app’s document root directory.
您的HipHop虚拟机配置文件应该包含此代码(以及您可能须要的其余设置)。确保将SourceRoot设置更改成指向Slim应用程序的文档根目录。
Server {
SourceRoot = /path/to/public/directory
}
ServerVariables {
SCRIPT_NAME = /index.php
}
VirtualHost {
* {
Pattern = .*
RewriteRules {
* {
pattern = ^(.*)$
to = index.php/$1
qsa = true
}
}
}
}
复制代码
Ensure the Web.config and index.php files are in the same public-accessible directory. The Web.config file should contain this code:
确保Web.config和index.php文件位于同一个公共访问目录中。Web.config应该包含如下代码:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="slim" patternSyntax="Wildcard">
<match url="*" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="index.php" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
复制代码
Your lighttpd configuration file should contain this code (along with other settings you may need). This code requires lighttpd >= 1.4.24.
您的lighttpd配置文件应该包含此代码(以及您可能须要的其余设置)。这段代码须要lighttpd >= 1.4.24。
url.rewrite-if-not-file = ("(.*)" => "/index.php/$0")
复制代码
This assumes that Slim’s index.php is in the root folder of your project (www root).
这假设Slim的index.php位于项目的根文件夹(www root)中。
Congratulations! if you have made it this far, that means you have successfully built something awesome using Slim. However, the time to party has not come yet. We still have to push our application to the production server.
There are many ways to do this that are beyond the scope of this documentation. In this section, we provide some notes for various set-ups.
恭喜你!若是你已经作到了这一步,那就意味着你已经成功地使用Slim建立了一些很棒的东西。然而,聚会庆祝的时间尚未到。咱们仍然必须将应用程序推到生产服务器。
有许多本文档以外的方法一样能够作到这一点。在本节中,咱们将为各类设置提供一些注释。
The first thing to do is to tweak your settings (src/settings.php in the skeleton application) and ensure that you do not display full error details to the public.
首先要作的是调整设置(骨架应用程序中的src/settings.php),并确保不会向公众显示完整的错误细节。
'displayErrorDetails' => false, // set to false in production
复制代码
You should also ensure that your PHP installation is configured to not display errors with the php.ini setting:
display_errors = 0
复制代码
If you control your server, then you should set up a deployment process using any one of the many deployment system such as:
若是你控制你的伺服器,你应该使用如下任何一个部署系统来创建部署过程:
If your shared server runs Apache, then you need to create a .htaccess file in your web server root directory (usually named htdocs, public, public_html or www) with the following content:
若是共享服务器运行Apache,则须要在web服务器根目录(一般名为htdocs、public、public_html或www)中建立一个.htaccess文件,内容以下:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^$ public/ [L]
RewriteRule (.*) public/$1 [L]
</IfModule>
复制代码
(replace ‘public’ with the correct name of your domain name e.g. example.com/$1)
将“public”替换为您的域名的正确名称,例如example.com/$1
Now upload all the files that make up your Slim project to the webserver. As you are on shared hosting, this is probably done via FTP and you can use any FTP client, such as Filezilla to do this.
如今将构成Slim项目的全部文件上传到web服务器。因为您是在共享主机上,这多是经过FTP完成的,您可使用任何FTP客户机,好比Filezilla来完成这一任务。