How to use composer included items? - composer-php

In my composer.json file I added "kigkonsult/icalcreator": "v2.23.7" to the required list, and after doing the install I see that directory in existence under the vendor dir. I can't figure out how to "use" it though in my PHP files in this project.
If I weren't using composer I'd just require the icalcreator.php file in that area. What's the right syntax when I include it via composer?

Once the package is installed you need to add the composer autoloader somewhere in your project.
require_once('/path/to/vendor/autoload.php');
Normally Composer uses PSR-4 autoloading, but it looks like this package doesn't. It just adds it's own autoloader to composer so just including the Composer loader should be sufficient.
Once the autoloader is added you can just use the package however you need. Composer will automatically register the packages custom autoloader and PHP will use that to load the appropriate file.

Related

Calling class from vendor

EDIT Autoload
require __DIR__ . '/../../../vendor/autoload.php';
I am calling it this way:
$generatorSVG = new \Picqer\Barcode\BarcodeGeneratorSVG();
The error:
Message: Class 'Picqer\Barcode\BarcodeGeneratorSVG' not found
The class exist. I am not installing it via composer but copying it in the vendor folder, because I dont have composer and the server and dont have permissions to install it.
Using PHPStorm and by ctrl+click on the class leads me to it. I am wrong with the proper calling it in CI ?
Manually copying files in the vendor directory is not enough, because Composer generates a bunch of lookup files (vendor/composer/autoload_*.php) to be able to figure out where the files are located that you want to load via Composer's autoloader.
Either, you should composer require the package you want to install or require all your source files manually in your bootstrap.php or index.php.
If this is a custom package you built, be aware that Composer can also pull it directly from a Git instance, local directory, or zip file. There's no need to create a public package on Packagist or self-host it with Satis. Check the Composer docs on how to configure repositories to find out more.

Composer install and update: why does it not set the PHP interpretor in the "vendor" folder?

According to docs, composer install (composer update too, since it includes install script), among other things, downloads the requirements and puts these packages inside the vendor directory: https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies :
It then implicitly runs the install command. This will download the dependencies' files into the vendor directory in your project.
What the docs don't say is: we often write the following in composer.JSON...
"require": {
"php": "^8.0",
... so if we try to apply what the docs say, it means that Composer would download the PHP interpretor (a package available in Packagist for example) and put it inside the vendor directory, when we run either composer install or composer update. What is the interest of putting a PHP interpretor inside a site's folder (here, vendor)?
But we know it doesn't do that. It won't download any PHP interpretor. It won't obviously put it inside the vendor directory. Instead, it will just check the server's PHP interpretor's version and returns a fatal error or something else if this version doesn't match the requirement's version.
So does it mean that in the Composer's install and update scripts, there is an exception made for PHP when treating the require's lines in the composer.JSON file?
In composer there's a special exception for require php, it only checks if your system's PHP version meets the requirement.
It's in the composer website under Package links: https://getcomposer.org/doc/04-schema.md#package-links.
Its not literally written though, its quite hard to find in the composer documentation.
If your require contains something like with
"php": "^8.0",
"ext-json": "*",
this does not mean: Install PHP or the JSON extension through Composer, but require that PHP and that extension in the given versions are already installed. That's what the documentation at https://getcomposer.org/doc/04-schema.md#package-links tells you:
require and require-dev also support references to specific PHP versions and PHP extensions your project needs to run successfully.
A regular expression that matches all such platform requirements can be found at https://github.com/composer/composer/blob/9ba042ded8b26230d33ebceb692bf29111d51ba4/src/Composer/Repository/PlatformRepository.php#L34 - currently, it contains:
const PLATFORM_PACKAGE_REGEX = '{^(?:php(?:-64bit|-ipv6|-zts|-debug)?|hhvm|(?:ext|lib)-[a-z0-9](?:[_.-]?[a-z0-9]+)*|composer-(?:plugin|runtime)-api)$}iD';
...which matches:
PHP runtimes in several versions
HHVM, a virtual machine that runs a forked version of PHP
all kinds of extensions and core libraries, like ext-json or lib-bz2
Composer itself, as some packages require special features of Composer v2 which were not available in v1
All lines in require section of composer.JSON are not packages available on a repository like Packagist: indeed, we can put some "virtual packages" inside this require section (https://getcomposer.org/doc/01-basic-usage.md#platform-packages).
php is one of these virtual packages. So Composer treat the following line...
"require": {
"php": "^8.0",
... as a virtual package (other name: "plateform package"), and not a package that could be put in vendor.
Then, if we extend a little the following definition of require...
Map of packages required by this package. The package will not be installed unless those requirements can be met.
(https://getcomposer.org/doc/04-schema.md#require)
..., then we can say that "if server's PHP interpretor's version doesn't meet the requirements versions, then Composer will raise a fatal error or something like that.
**Conclusion: being seen as a "virtual/plateform package" by Composer, php won't be installed (put) in vendor directory. It will just make Composer to check if server PHP version matches or not the requirements (if not, an error will be raised). This behavior is different than for other packages that would be, them, downloaded from for example Packagist and installed (put) inside vendor directory. **

composer is not removing entry from composer.lock

I've used following command to remove a package using composer.
composer remove sjparkinson/static-review
Above command removes entry from composer.json file but composer.lock file still contains entry for mentioned library in require section.
What is the proper way to update composer.lock ? Should I update it manually?
Composer does not removing this package, because it is required by another dependency. So even if you don't require it directly, it is still required by your project, so you cannot remove it. You can use composer why some-vendor/some-package command to check what is the reason to keep this package installed:
composer why sjparkinson/static-review
magento/product-community-edition 2.2.4 requires sjparkinson/static-review (~4.1)
If you really want to remove this package, you need to remove magento/product-community-edition too (and every dependency, which depends on this package).
BTW: Editing composer.lock manually is really bad idea, you should never do that.

Refactoring Composer executable file for portability

Installing Composer locally puts a file named composer in your directory. I have taken to copying this file into each of my projects that uses Composer, so that I can run php composer in each folder.
Since this results in a lot of needlessly-repeated code, I want to refactor the composer file into something minimal. The most logical solution would be to refer to a class that resides in the vendor folder. Why is there so much code in the composer file anyway? I'd prefer not to put the code into my own libraries if I don't have to.
For comparison, here's a sample of code in a typical phpunit file:
require_once 'my_bootstrap.php';
spl_autoload_register(array(MyBootstrap::class,'autoload'));
// Do some other stuff here.
\PHPUnit_TextUI_Command::main();
I want to reduce the composer file in each project to something like this.
I do not want to install Composer globally. I want each project to be an environment unto itself and not have to instruct another developer to install anything other than PHP.

what's the purpose of composer's `require` command

Here is the definitions from the docs:
The require command adds new packages to the composer.json file from
the current directory. If no file exists one will be created on the
fly. After adding/changing the requirements, the modified requirements
will be installed or updated.
If you do not want to choose requirements interactively, you can just
pass them to the command.
I can't seem to understand the purpose of the require command and the difference from install. Can you elaborate on that?
And here is the example of using the command:
composer global require "fxp/composer-asset-plugin:~1.0.3"
Can you tell me what's the difference from:
composer global install "fxp/composer-asset-plugin:~1.0.3"
It's just a convention. There might be some fallbacks in other commands for common people missuses, but every command is optimized for a different feature. It's just better user experience.
Same goes for similarity of composer install and composer update.
As for conventions, in order of common workflow:
composer install is for installing all packages of new application (all mentioned in composer.json), use: composer install
composer require is for adding a new package, use: composer require symfony/symfony
composer update is for updating current dependencies, use: composer update
composer require->It will write the modules in composer.json file and install the module.
composer install->It will install the modules which are already present in the composer.json file.

Categories

Resources