简体   繁体   English

使用没有Composer的PHP包

[英]Using PHP Packages without Composer

I'm building an SDK for developers to use to build modules for ecommerce platforms that will consume our API for a new startup. 我正在为开发人员构建一个SDK,用于为电子商务平台构建模块,这些模块将使用我们的API进行新的启动。

Obviously it would be ideal to use composer, which I am doing right now. 显然,使用作曲家是理想的,我现在正在做。 But as I examine most of the ecommerce platforms out there right now, or at least the most popular ones, they don't use composer. 但是,当我现在检查大多数电子商务平台,或者至少是最受欢迎的电子商务平台时,他们不会使用作​​曲家。

So I'm wondering what's the best way to get all the dependencies all my current packages need and build them into a freestanding SDK. 所以我想知道什么是获得我当前所有软件包所需的所有依赖项的最佳方法,并将它们构建为独立的SDK。

This way I can have a version that will work for both composer and non-composer enabled platforms. 这样我就可以拥有一个适用于作曲家和非作曲家启用平台的版本。

Is there a standardized way to do this in terms of a design pattern? 在设计模式方面有没有标准化的方法来做到这一点? How would I lay out all the dependency packages in any organized way? 我将如何以任何有组织的方式布置所有依赖包?

Because those e-commerce platforms don't use composer, that doesn't force you to exclude composer from equation. 因为那些电子商务平台不使用composer,所以这并不会强迫你将composer排除在等式之外。 You can't distribute your package as a plugin/module/whatever for that particular e-commerce platform, but you can still use composer's autoloader in production. 您不能将您的软件包作为插件/模块/分发给特定的电子商务平台,但您仍然可以在生产中使用composer的自动加载器。

You could prepare the package for deployment on your machine or on a build server, archive the result and distribute the archive. 您可以准备程序包以在计算机或构建服务器上进行部署,归档结果并分发存档。 For the sake of simplicity, my example will assume that you will prepare your package on your local machine: 为简单起见,我的示例将假设您将在本地计算机上准备包:

  1. Create a temporary working directory: 创建一个临时工作目录:

     $ mkdir -p ~/.tmp && cd ~/.tmp 
  2. Clone your package: 克隆你的包裹:

     $ git clone <package> 
  3. Install dependencies 1 安装依赖项1

     $ cd ~/.tmp/<package> && composer.phar install --no-dev --optimize-autoloader 

    or if you do this from an automated tool: 或者如果您使用自动化工具执行此操作:

     $ cd ~/.tmp/<package> && composer.phar install --no-ansi --no-dev --no-interaction --no-progress --no-scripts --optimize-autoloader 
  4. Remove .git directory. 删除.git目录。

  5. Create the zip/tar archive from ~/.tmp/<package> ~/.tmp/<package>创建zip / tar存档

  6. Distribute the archive. 分发存档。

Assuming that your package is already a plugin/module for that e-commerce platform, it can be installed as usual from that zip/tar archive. 假设您的软件包已经是该电子商务平台的插件/模块,它可以像往常一样从该zip / tar存档安装。


1) Regarding --optimize-autoloader , please read this answer from Sven, which explains why in some cases doesn't help your application to become faster. 1)关于--optimize-autoloader ,请阅读Sven的回答 ,这解释了为什么在某些情况下无法帮助您的应用程序变得更快。

Don't have dependencies! 没有依赖!

Yes, seriously. 是的,认真的。 If you'd develop an API client that would use Guzzle as the HTTP client, you'd have to make a choice: Use Guzzle version 3, 4, 5 or 6? 如果你开发一个使用Guzzle作为HTTP客户端的API客户端,你必须做出选择:使用Guzzle版本3,4,5或6?

Guzzle 3 is out of maintenance and abandoned. Guzzle 3没有维护而被遗弃。 You wouldn't want to use it. 你不会想要使用它。

Guzzle 4 is also considered end-of-life, because version 5 came very fast. Guzzle 4也被认为是生命终结,因为第5版的速度非常快。 Nobody really use this version. 没人真正使用这个版本。

This boils down to using either version 5 or 6. But Guzzle is using the same namespace and likely the same class names in both versions, but is incompatible to each other. 这可以归结为使用版本5或版本6.但Guzzle在两个版本中使用相同的命名空间并且可能使用相同的类名,但彼此不兼容。 No matter which version you choose: Your customer will have made the opposite choice - and now you have a codebase where two versions of Guzzle are running at the same time - this will not work. 无论您选择哪个版本:您的客户都会做出相反的选择 - 现在您有一个代码库,其中两个版本的Guzzle同时运行 - 这是行不通的。

If you don't have dependencies, but deliver everything within your own codebase, you have all of your code under your control, and are reducing the need to use Composer as a tool to easily install all your dependencies. 如果您没有依赖项,但是在您自己的代码库中提供所有内容,那么您可以控制所有代码,并且不再需要使用Composer作为工具来轻松安装所有依赖项。 Your package will have everything already included, it's unlikely that there will be any namespace conflicts. 你的包将包含所有内容,不太可能存在任何命名空间冲突。

You'd be able to offer a ZIP file for download. 您可以提供ZIP文件供下载。 And if you additionally offer a composer.json to allow developers to include your package that way, everyone will be happy. 如果您另外提供composer.json以允许开发人员以这种方式包含您的包,那么每个人都会很高兴。

Update 更新

Now after finding out that everyone thinks I am crazy proposing not to use stuff invented elsewhere, I challenge you to think about the situation once again: You find that you have to produce code that will likely be included in a codebase that is NOT managed with Composer. 现在在发现每个人都认为我疯狂建议不使用其他地方发明的东西之后,我再次挑战你再考虑一下情况:你发现你必须生成可能包含在未经过管理的代码库中的代码作曲家。 That means you have no idea what kind of software is put together there. 这意味着你不知道那里放了什么样的软件。

It may simply be so that you have a version of Guzzle in the existing codebase - undetectable, because there is no composer.json . 可能只是因为你在现有的代码库中有一个Guzzle版本 - 不可检测,因为没有composer.json Now you provide your own package with a bundled Guzzle version (whatever way made it appear there). 现在你提供自己的包装,带有捆绑的Guzzle版本(不管它出现在哪里)。 This will likely crash the entire software at some point because of conflicts, because the autoloading will of course be merged at some point, and then some part of the code will request some Guzzle class to be loaded, which is included twice from two different versions of Guzzle. 由于冲突,这可能会在某些时候崩溃整个软件,因为自动加载当然会在某个时候合并,然后代码的某些部分将请求加载一些Guzzle类,其中包括两个不同版本的两次Guzzle。

WHAT SHOULD HAPPEN IN THIS CASE? 在这种情况下应该发生什么? THINGS WILL CRASH! 事情会崩溃!

And it is unavoidable that this will happen. 这种情况不可避免地会发生。 Even in the lucky case of being able to use Composer, it will conflict - the software won't crash, but the entire package won't be installed. 即使在能够使用Composer的幸运情况下,它也会发生冲突 - 软件不会崩溃,但整个软件包都不会安装。 The good thing is: You will notice this immediately. 好消息是:你会立即注意到这一点。

If the primary goal is to deliver an API client anyone can use in every situation, without using a dependency manager: Don't have dependencies! 如果主要目标是提供API客户端,那么任何人都可以在不使用依赖管理器的情况下使用它: 不要依赖!

Alternatively, be completely sure that you know which software is already being used, and create a package that will not conflict in any case. 或者,完全确定您知道哪些软件已被使用,并创建一个在任何情况下都不会冲突的软件包。 However, this is still an effort, because there might be other addons also being installed, which might include conflicting software. 但是,这仍然是一项努力,因为可能还安装了其他插件,其中可能包含冲突的软件。

My central point is: If you don't have a dependency manager like Composer being able to manage the dependencies, you are better off NOT to have dependencies in your own code to make it super easy to include your own code in someone else code base. 我的中心观点是:如果您没有像Composer这样的依赖管理器能够管理依赖项,那么最好不要在自己的代码中使用依赖项,以便将自己的代码包含在其他代码库中变得非常容易。 。

And the question above clearly states that Composer is not an option in the general case. 上面的问题清楚地表明,在一般情况下,Composer不是一个选项。

Now there is one light at the end of the tunnel: When it comes to general tasks, the PHP-FIG has started to standardize interfaces that should leverage interoperability. 现在隧道尽头有一个亮点:当涉及到一般任务时,PHP-FIG已经开始标准化应该利用互操作性的接口。 For HTTP, the standard is PSR-7. 对于HTTP,标准是PSR-7。

You COULD provide an API SDK that depends (and brings with it) the PSR-7 interface and requires the user of the SDK to provide a HTTP client that implements this interface. 您可以提供依赖(并带有)PSR-7接口的API SDK,并要求SDK的用户提供实现此接口的HTTP客户端。

The problem with this approach I see is that you will still run into trouble if you try to use for example Guzzle for the same reason: The only valid choice now is to use Guzzle 6 for the SDK - what if Guzzle 5 was already used elsewhere? 我看到这种方法的问题是,如果你因为同样的原因尝试使用例如Guzzle,你仍然会遇到麻烦:现在唯一有效的选择是使用Guzzle 6作为SDK - 如果Guzzle 5已经在其他地方使用过? Conflict! 冲突! The good thing is: You can avoid using Guzzle 6 if you are already using Guzzle 5 by using any other PSR-7 capable HTTP client. 好处是:如果您已经使用任何其他支持PSR-7的HTTP客户端使用Guzzle 5,则可以避免使用Guzzle 6。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM