About using of packages that your composer library suggests - php

I am developing some composer php library.
And I want to provide library users to use class that uses some external package. I suggest this package in the relevant composer section.
Should I check that the composer's suggested package is really installed?
Will there be an error if the user just install my library without suggestions, but will not use this class that dependent from not installed package?
I checked some popular packages and seems to be they just use suggested packages as if they are already installed.
For example: https://github.com/Seldaek/monolog/blob/c861fcba2ca29404dc9e617eedd9eff4616986b8/src/Monolog/Handler/ElasticsearchHandler.php
This monolog class just uses Elasticsearch classes as usual, but Elasticsearch is a suggested package and may be not installed.

The handlers use the other packages as if they were installed - but keep in mind that Monolog does not use each and every handler automatically. If you define that such a handler (in your example: the one for ElasticSearch) is used, it is up to the user to know how to handle this.
As you can see in the constructor of that method, it is not even instantiable if you don't have a package for ElasticSearch installed - the code example in that class helps to understand this situation. So, no, this class is not usable without having another package installed, but the error will be thrown by your classloader. No need for the package to check for this

Related

Symfony - manually add phpxmlrpc to vendor

I need to use XML-RPC on my project. I have found a library phpxmlrpc (http://phpxmlrpc.sourceforge.net/) and I need to add it to vendor. I have copied the files in vendor folder (/vendor/phpxmlrpc/) and I need to see the xmlrpc_client class in my Controller. But I am not able to manage how to edit autoload.php to see the class, after a few attemps I am still getting "Attempted to load class "xmlrpc_client" from the global namespace.
Did you forget a "use" statement?" so I am pretty sure that there is some mess in my structure. I would really appreciate any help.
You must use a composer install tools for integrate 3third party code in your project a lot of possible time.
For XML-RPC you have this bundle : Symfony-rpc-bundle
When you install with composer install your bundle a lot of tricks run in your project symfony. Don't forget to add this bundle in your AppKernel.php file.
With this your code for XML-RPC is more upkeeping and stable.
A bit late with the answer, I fear, but phpxmlrpc can now be installed using Composer as you would do with any other package.
When checking out info about that library, just make sure that you look up the latest version on GitHub and not any more on SourceForge.

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.
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.
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. 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.
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:
Create a temporary working directory:
$ mkdir -p ~/.tmp && cd ~/.tmp
Clone your package:
$ git clone <package>
Install dependencies1
$ 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
Remove .git directory.
Create the zip/tar archive from ~/.tmp/<package>
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.
1) Regarding --optimize-autoloader, please read this answer from Sven, which explains why in some cases doesn't help your application to become faster.
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 3 is out of maintenance and abandoned. You wouldn't want to use it.
Guzzle 4 is also considered end-of-life, because version 5 came very fast. 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. 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.
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. 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. And if you additionally offer a composer.json to allow developers to include your package that way, everyone will be happy.
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. Now you provide your own package with a bundled Guzzle version (whatever way made it appear there). 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.
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. 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!
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.
And the question above clearly states that Composer is not an option in the general case.
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. For HTTP, the standard is 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.
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? 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.

how to use wepay PHP sdk in laravel 5?

I want to use wepay PHP sdk in laravel 5 using composer but I didn't found any laravel package for it.
Can you please tell me me how can I do this?
The package is available via packagist.org - unfortunately only as a dev-master branch and with suboptimal autoloading configured (I'm trying to fix that, sent both a patch and opened an issue suggesting they tag their version).
Adding that package is basic Composer action. The classes should be automatically available within Laravel wherever you think you want to use it.

How to install modern PHP packages?

How do I install modern PHP packages? I haven't used PHP for 5 years so everything seems new.
In particular I'm trying to install https://github.com/pda/pheanstalk. I downloaded the code, but when I try to
require_once 'Pheanstalk/Pheanstalk.php'
I get an error:
Fatal error: Interface 'Pheanstalk\PheanstalkInterface' not found
in /web/Pheanstalk/Pheanstalk.php
I found I should use use. When I try use Pheanstalk\Pheanstalk I get this error:
Fatal error: Class 'Pheanstalk\Pheanstalk' not found in /web/test.php on line 5
Can't I just download and use PHP code anymore like back in the day? How do I get these modern packages working? Packages seem to mention composer. Should I use that? Can't I just download code and use it? I don't want to depend on composer or any other package manager. I just want to run code.
The modern way of installing packages is to use Composer.
It might seem scary at first, but it isn't such a big deal.
You should also be able to download and use the package yourself, if the creator made that possible, it should be explained in the documentation however.
There might be no "easy" way to install your package without composer if the package creator intended it that way. For this package in particular, the only instructions are for Composer, so it's safe to assume that it's the easiest way to install it.
Of course it's possible to use his code directly, but you'll need to know what you're doing and understand namespaces.

Issue when using a package (pagseguro/php) with composer in a laravel app, apparently it is not loading or initializing itself

I have a laravel app and i want to use the pagseguro/php package.
I added it to the composer.json and updated. I can access the main class (PagSeguroPaymentRequest) without a problem.
At some point I have to call this:
PagSeguroConfig::getAccountCredentials();
But it throws an exception. After reading code around I thought on trying to init the library by myself and suddenly everything worked:
PagSeguroLibrary::init();
This method is inside the only php file in source/PagSeguroLibrary/
Shouldn't composer automatically execute this method? What is exactly "loading" a package? Is there anyway to fix this using composer only?
Thank you all.
Shouldn't composer automatically execute this method?
No, it shouldn't. Composer is a package and dependency manager program. It's job is to
Get PHP files into your vendor folder
If using those PHP files means you need other PHP files, get those other PHP files into your vendor folder
Setup things so that class files from the packages are correctly autoloaded in PHP (i.e. no need to require or include stuff yourself)
Composer packages work independent of frameworks. Someone could distribute a laravel service provider via a computer package, or someone could distribute code that doesn't know anything about Laravel. How each composer package works is up to the author (always read the README)
In the case of pagseguro/php, it looks like you're supposed to instantiate a PagSeguroPaymentRequest object which, when autoloaded, will automatically call init. The examples distributed with the package also makes it look like this package was code that predated composer, and still uses many manual includes and requires.

Categories