php-fpm启动方法

tech2022-09-16  67

php-fpm启动方法

Back when we covered Diffbot, the visual AI-enhanced machine-learning crawler, we also mentioned they have libraries for a wide array of programming languages, but those are often less than cutting edge – with so many to keep an eye on, there’s bound to be a few bad apples that slip through the cracks. One such apple is their PHP library, and we’ll be building an alternative in this series, in an effort to do it better.

回顾当我们介绍了Diffbot (可视化AI增强的机器学习搜寻器)时,我们还提到了它们具有用于多种编程语言的库,但是这些库通常都不是最先进的,因为有很多需要注意的地方,会是一些破烂的苹果。 这样的苹果就是他们PHP库,我们将在本系列中构建一个替代品,以期使其做得更好。

Note that this tutorial will focus on writing a good package – the code we write will be real and production-ready, but you shouldn’t focus too much on Diffbot itself. Diffbot’s API is simple enough and Guzzle’s interface is smooth enough to just consume it outright without the need for a PHP library anyway. Rather, pay attention to the approaches we use to develop a high quality PHP package, so you can reuse them in your own project. Diffbot was selected as the subject of the package because I’d like to demonstrate best practices on a real world example, rather than yet another “Acme” package.

请注意,本教程将专注于编写一个好的程序包-我们编写的代码将是真实的并且可以投入生产,但是您不应过多地关注Diffbot本身。 Diffbot的API非常简单,而Guzzle的界面也足够平滑,可以直接使用它而无需使用PHP库。 相反,请注意我们用于开发高质量PHP软件包的方法,因此您可以在自己的项目中重复使用它们。 选择Diffbot作为软件包的主题是因为我想在一个真实的例子中演示最佳实践,而不是另一个“ Acme”软件包。

好的包装设计 (Good Package Design)

In recent years, good standards for PHP package design have popped up, in no small part due to Composer, Packagist, The League and, most recently, The Checklist. Putting all these in a practical list we can follow here, but avoiding any tight coupling with The League (since our package won’t be submitted there – it’s specifically made for a third party API provider and as such very limited in context), the rules we’ll follow are:

近年来,出现了PHP软件包设计的良好标准,这在很大程度上要归功于Composer , Packagist , The League以及最近的The Checklist 。 将所有这些放入实用列表中,我们可以在此处遵循,但要避免与The League紧密联系(因为我们的软件包不会在那里提交-它是专门为第三方API提供程序制作的,因此在上下文中非常有限),我们将遵循的规则是:

include a license

包括许可证 be open source (well, duh!)

开源(恩,,!) exclude development stuff from dist

从dist中排除开发内容 use PSR-4 autoloading

使用PSR-4自动加载 be hosted on Packagist for Composer installation

托管在Packagist上以进行Composer安装 be framework agnostic

与框架无关 use PSR-2 coding standard

使用PSR-2编码标准 have in depth code comments

有深入的代码注释 use semantic versioning

使用语义版本控制 use CI and Unit Tests

使用CI和单元测试

For a more detailed reading of these and more rules, see here.

有关这些规则和更多规则的详细说明,请参见此处 。

入门 (Getting Started)

Naturally, we’ll be using our trusty Homestead Improved box again, as it’s the quickest way to get started developing on a unified environment. For your reference, I chose the following vhosts, and will be using them throughout the rest of this tutorial:

自然,我们将再次使用可信赖的Homestead改良盒,因为这是开始在统一环境上开发的最快方法。 供您参考,我选择了以下虚拟主机,并将在本教程的其余部分中使用它们:

sites: - map: test.app to: /home/vagrant/Code/diffbot_lib - map: test2.app to: /home/vagrant/Code/diffbot_test

OK, after getting into the VM, let’s start hacking away.

好的,进入虚拟机之后,让我们开始黑客入侵。

To hit the ground running, we’ll use the League Skeleton, which is a template package with League rules embedded, allowing for a head start. I’ve made my own fork with a better .gitignore and some minor tweaks if you’d like to use that – if not, just use theirs, the difference is truly trivial.

要开始运作,我们将使用League Skeleton ,这是一个嵌入了League规则的模板包,可以抢占先机。 如果您想使用它,我会用更好的.gitignore和一些细微的调整来制作自己的分叉 –如果不使用,只需使用它们的差异就可以了。

git clone https://github.com/Swader/php_package_skeleton diffbot_lib

We edit the composer.json file and end up with something like this:

我们编辑composer.json文件,最后得到如下内容:

{ "name": "swader/diffbot_client", "description": "A PHP wrapper for using Diffbot's API", "keywords": [ "diffbot", "api", "wrapper", "client" ], "homepage": "https://github.com/swader/diffbot_client", "license": "MIT", "authors": [ { "name": "Bruno Skvorc", "email": "bruno@skvorc.me", "homepage": "http://bitfalls.com", "role": "Developer" } ], "require": { "php" : ">=5.5.0" }, "require-dev": { "phpunit/phpunit" : "4.*" }, "autoload": { "psr-4": { "Swader\\Diffbot\\": "src" } }, "autoload-dev": { "psr-4": { "Swader\\Diffbot\\Test\\": "tests" } }, "extra": { "branch-alias": { "dev-master": "1.0-dev" } } }

We set some common meta data, define the requirements, and set up PSR-4 autoloading. This, along with the fact that we’re using the League Skeleton, takes care of points 1-6 on our to-do list from above. While we’re here, we can also add Guzzle to our requirements, as it’s the HTTP client library we’ll be using to make all calls to Diffbot API points.

我们设置一些通用的元数据,定义需求,并设置PSR-4自动加载。 这以及我们使用的是联赛骨架的事实,可以从上方处理待办事项清单上的1-6点。 当我们在这里时,我们还可以将Guzzle添加到我们的需求中,因为它将使用HTTP客户端库对Diffbot API点进行所有调用。

"require": { "php" : ">=5.5.0", "guzzlehttp/guzzle": "~5.0" },

After running composer install, which will pull in all the dependencies, including PHPUnit we’ll need for testing, we can check if everything is working by changing the contents of src/SkeletonClass.php to:

运行composer install ,它将获取所有依赖项,包括我们需要测试PHPUnit,我们可以通过将src/SkeletonClass.php的内容更改为以下内容来检查一切是否正常:

<?php namespace Swader\Diffbot; class SkeletonClass { /** * Create a new Skeleton Instance */ public function __construct() { } /** * Friendly welcome * * @param string $phrase Phrase to return * * @return string Returns the phrase passed in */ public function echoPhrase($phrase) { return $phrase; } }

and creating an index.php file in the root of the project:

并在项目的根目录中创建一个index.php文件:

<?php require_once "vendor/autoload.php"; $class = new \Swader\Diffbot\SkeletonClass(); echo $class->echoPhrase("It's working");

Visiting test.app:8000 in the browser should now yield the “It’s working” message.

现在,在浏览器中访问test.app:8000将会显示“正在运行”消息。

Don’t worry about not having a public directory or anything of the sort – this is not important when building a package. When building a library, all the focus should be on the package, and only on the package – no need to deal with frameworks or MVC. We’ll use the index.php file for testing some stuff out from time to time, but mostly, we’ll be using PHPUnit to develop our library. For now, let’s add index.php to .gitignore to make sure we don’t accidentally send it upstream.

不用担心没有public目录或任何种类的东西–在构建软件包时这并不重要。 构建库时,所有焦点都应该放在程序包上,而只在程序包上–无需处理框架或MVC。 我们将不时使用index.php文件来测试一些东西,但是大多数情况下,我们将使用PHPUnit开发我们的库。 现在,让我们将index.php添加到.gitignore ,以确保我们不会意外地将其发送到上游。

PSR-2 (PSR-2)

To keep in sync with modern standards, we’d do best to implement PSR-2 from the get-go. I use PhpStorm, so this is dead easy to do. You can either choose the built-in PSR1/PSR2 standards, like so, or you can install and activate CodeSniffer and use it as a PhpStorm inspection, like so. I opted for the former, because remote execution of PHPCS via PhpStorm is not yet supported (and a Vagrant VM is, for all intents and purposes, remote), but if you’d like to help out with adding this feature to PhpStorm, please vote here.

为了与现代标准保持同步,我们最好从一开始就实施PSR-2。 我使用PhpStorm,所以这很容易做到。 您可以选择内置的PSR1 / PSR2标准, 像这样 ,也可以安装并激活CodeSniffer并把它作为一个PhpStorm检查, 像这样 。 我之所以选择前者,是因为尚不支持通过PhpStorm远程执行PHPCS(出于各种目的和目的,Vagrant VM是远程的),但是如果您想帮助将此功能添加到PhpStorm中,请在这里投票。

You can still require CodeSniffer in your project as usual via Composer and run it from the VM’s command line, though:

您仍然可以像往常一样通过Composer在项目中要求CodeSniffer并从VM的命令行运行它,但是:

You can also opt to only install PHP on your host machine (as opposed to additional nonsense that comes with a standard XAMPP/WAMP installation), download CodeSniffer there, and use it like that. You’d use your host machine only for code inspection, while developing and running your package logic from the VM. It’s a bit awkward, but helps when using IDEs like PhpStorm, at least until the aforementioned issue is implemented.

您还可以选择仅在主机上安装PHP(而不是标准XAMPP / WAMP安装附带的其他废话),在那里下载CodeSniffer并像这样使用它。 从VM开发和运行程序包逻辑时,仅将主机用于代码检查。 有点尴尬,但是至少在使用上述问题之前,在使用PhpStorm等IDE时会有所帮助。

If you’re not using PhpStorm, look for alternatives on how to accomplish this, but make sure you do – we need PSR2.

如果您不使用PhpStorm,请寻找替代方法来实现此目的,但请确保您已这样做–我们需要PSR2。

规划 (Planning)

With our bootstrapping out of the way, we can start developing. Let’s think about everything we need.

通过我们的引导程序,我们可以开始开发。 让我们考虑一下我们需要的一切。

入口点 (Entry point)

No matter what the use case for Diffbot’s API, a user will want to create an instance of the API client – there’s nothing you can do with Diffbot other than query the pre-made APIs. Each API use also needs a developer token which is to be passed in the request as a query param, in the form of ?token=xxxxxx. My reasoning is as follows: a single developer will usually be using a single token, so aside from allowing developers to create new API client instances and passing in a token (say, in the constructor), we should also have a way of defining a global token to be used in all future instantiations. In other words, we want both of these approaches to be valid:

无论Diffbot API的用例是什么,用户都将要创建API客户端的实例-除了查询预制的API外,Diffbot无法做任何事情。 每次使用API​​都需要一个开发者令牌,该令牌将以?token=xxxxxx的形式在查询中作为查询参数传递。 我的推理如下:单个开发人员通常将使用单个令牌,因此,除了允许开发人员创建新的API客户端实例并传入令牌(例如,在构造函数中)外,我们还应该有一种定义在将来的所有实例化中使用的全局令牌。 换句话说,我们希望这两种方法都有效:

$token = xxxx; // approach 1 $api1 = new Diffbot($token); $api2 = new Diffbot($token); // approach 2 Diffbot::setToken($token); $api1 = new Diffbot(); $api2 = new Diffbot();

The former approach helps when you’re creating a single API client instance, or you’re using several tokens (maybe you have one for Crawlbot, and one for regular APIs). The latter approach works well when you’ve defined many API endpoints for your application to consume and will be needing several, but don’t want to re-inject the token every time.

当您创建单个API客户端实例或使用多个令牌(也许您有一个用于Crawlbot的令牌,而一个用于常规API的令牌)时,前一种方法会有所帮助。 当您为应用程序定义了许多API终结点以供使用时,并且将需要多个终结点,但又不想每次都重新注入令牌时,后一种方法效果很好。

With that in mind, let’s go ahead and make our package’s first class. Create the file src/Diffbot.php.

考虑到这一点,让我们继续前进,使我们的包装成为一流的。 创建文件src/Diffbot.php 。

<?php namespace Swader\Diffbot; use Swader\Diffbot\Exceptions\DiffbotException; /** * Class Diffbot * * The main class for API consumption * * @package Swader\Diffbot */ class Diffbot { /** @var string The API access token */ private static $token = null; /** @var string The instance token, settable once per new instance */ private $instanceToken; /** * @param string|null $token The API access token, as obtained on diffbot.com/dev * @throws DiffbotException When no token is provided */ public function __construct($token = null) { if ($token === null) { if (self::$token === null) { $msg = 'No token provided, and none is globally set. '; $msg .= 'Use Diffbot::setToken, or instantiate the Diffbot class with a $token parameter.'; throw new DiffbotException($msg); } } else { self::validateToken($token); $this->instanceToken = $token; } } /** * Sets the token for all future new instances * @param $token string The API access token, as obtained on diffbot.com/dev * @return void */ public static function setToken($token) { self::validateToken($token); self::$token = $token; } private static function validateToken($token) { if (!is_string($token)) { throw new \InvalidArgumentException('Token is not a string.'); } if (strlen($token) < 4) { throw new \InvalidArgumentException('Token "' . $token . '" is too short, and thus invalid.'); } return true; } }

The method also references a DiffbotException, so real quick, just make the file src/exceptions/DiffbotException.php with the contents:

该方法还引用了DiffbotException ,因此非常快,只需将文件src/exceptions/DiffbotException.php包含以下内容即可:

<?php namespace Swader\Diffbot\Exceptions; /** * Class DiffbotException * @package Swader\Diffbot\Exceptions */ class DiffbotException extends \Exception { }

Let’s quickly explain the Diffbot class.

让我们快速解释一下Diffbot类。

The token static property will serve as the default which Diffbot will use if no token is provided in the constructor while building a new instance. In that case, it gets copied into the instanceToken property which is bound to instances.

如果构建新实例时在构造函数中未提供令牌,则token静态属性将用作Diffbot的默认值。 在这种情况下,它将被复制到绑定到实例的instanceToken属性中。

The constructor checks if a token was passed. If it wasn’t, it uses the predefined default token, or throws a DiffbotException if none was set – that’s what our Exception code above was for. If the token is OK, it gets set as the token of the instance. On the other hand, if the token was passed in, then that one gets copied into instanceToken. Note that in both cases, the token must be validated with the validateToken static method. This private method for now simply checks if the token is a string of a length of more than three characters – if not, it throws an invalid argument exception.

构造函数检查是否传递了令牌。 如果不是,它将使用预定义的默认令牌,如果未设置默认令牌,则抛出DiffbotException -这就是我们上面的Exception代码所针对的。 如果令牌正常,则将其设置为实例的令牌。 另一方面,如果传递了令牌,则该令牌将被复制到instanceToken 。 请注意,在两种情况下,都必须使用validateToken静态方法来验证令牌。 现在,此私有方法仅检查令牌是否是长度超过三个字符的字符串–如果不是,则抛出无效的参数异常。

Finally, there’s the setToken static method, which lets us set the aforementioned global token. Naturally, this one needs to get validated, too.

最后,还有setToken静态方法,它使我们可以设置上述全局令牌。 当然,这一点也需要得到验证。

Seeing as a Diffbot token is bound to its set of APIs, being able to change a token on an already existing instance of Diffbot would be crazy. As such, I’ve opted to allow the setting of a token only on instantiation, or globally for all future instances of Diffbot. Of course, if the token gets set globally, an instance can still override this setting. Also, the global token is mutable, because we want to be able to change the spawning condition of future instances, and changing it when instances already exist doesn’t affect them in any way.

鉴于Diffbot令牌已绑定到其API集,因此能够在已经存在的Diffbot实例上更改令牌会很疯狂。 因此,我选择仅在实例化时允许设置令牌,或者在以后的所有Diffbot实例中全局设置令牌。 当然,如果令牌是全局设置的,则实例仍可以覆盖此设置。 而且,全局令牌是可变的,因为我们希望能够更改未来实例的生成条件,并且在实例已经存在时进行更改不会以任何方式影响它们。

Notice also how everything is documented with docblocks – not overdocumented, but just enough to make it easy to understand for everyone else coming in.

还请注意,所有内容都使用docblocks进行了记录-并未过度记录,但足以使其他人容易理解。

结论 (Conclusion)

In this part, we got started with PHP package development by setting up a skeleton project with some basic functionality, and by configuring our environment. You can download the end result of part 1 here. In part 2, we’ll start writing some tests and some actual functionality, and we’ll get started with proper test driven development. Before we move on, are there any questions or comments regarding the current process? Leave them below!

在这一部分中,我们通过建立具有一些基本功能的框架项目并配置环境来开始PHP软件包的开发。 您可以在此处下载第1部分的最终结果。 在第2部分中,我们将开始编写一些测试和一些实际功能,并开始进行适当的测试驱动开发。 在我们继续之前,对当前流程是否有任何疑问或意见? 把它们留在下面!

翻译自: https://www.sitepoint.com/starting-new-php-package-right-way/

php-fpm启动方法

最新回复(0)