How to configure symfony check:requirements? - php

I am using Symfony for an application. This application needs particulars PHP extensions to work, such as PHP GD, which are not listed in the base Symfony requirements.
I would like to know if it's possible to kind of edit the base list of requirements to add those extensions for my application to have them listed under the symfony check:requirements console output.

This requirements will NOT be tested when you launch symfony check:requirements, because this command doesn't depend of your application, it only checks the capacity to use symfony on the server.
This command will always return the same result, even if you launch it in a directory where there is no composer.yaml file.
But, you can add the needed extension by updating the composer.json file:
...
"require": {
"php": "^7.2",
...
"ext-gd": "*",
"ext-json": "*",
...
"foo/bar-bundle": "^1.3",
...
}
So, if the GD extension isn't installed on your server, installation of your application will not start.

Related

How to load composer package from remote git when running in production, and load from local package when development environment? [duplicate]

This question already has answers here:
Using PHP Composer to develop a local package and then copy it on deploy
(2 answers)
Closed 1 year ago.
I have two composer files to run composer in each environment
"repositories": [
{
"type": "vcs",
"url": "https://github.com/igorhaf/laravel-admin"
}
],
"require": {
"php": "^7.2.5|^8.0",
"fideloper/proxy": "^4.4",
"guzzlehttp/guzzle": "^7.4",
"laravel/framework": "^7.0",
"laravel/telescope": "^3.0",
"laravel/tinker": "^2.5",
"encore/laravel-admin": "dev-master"
},
I want running laravel-admin from a local folder in my project (packages) when I am using local environment, but with the same composer.json file
If I understand your use case clearly, you develop custom Laravel package and you don't want to always have to push it before you test it in local.
There's absolutely a use case for it. I personally use it. With this approach, your composer.json can stay the same both on local and server. No need to change anything.
You would need the package https://github.com/franzliedke/studio . The documentation is quite explanatory. You install it globally via composer. composer global require franzl/studio though can be installed per project but that's quite tedious because you may only need it locally.
At the root of your project run studio load path/to/your/local/vendor/directory/* (if you want all packages in directory) or studio load path/to/your/local/package (for a single package. You may add multiple packages). This will generate a studio.json file at the root.
Eg.
{
"version": 2,
"paths": [
"path/to/local/vendor/directory/*",
"path/to/local/package"
]
}
Anytime you run composer update, composer will first look in your studio.json file and symlink to local packages if available, else get it from the remote repository.
Note:
i. Make sure to add studio.json to .gitignore.
ii. Also remove the paths from studio.json as seen below and run composer update to generate new composer.lock file before you push your code to production/server. Else your code on server will be looking for packages from the symlink in local setup when you run composer install and give you errors.
{
"version": 2,
"paths": [
]
}
iii. After pushing to server, return the studio.json to initial state and continue to develop. No need to push to github/remote vcs before you see your changes. Changes are symlinked from local if available or gotten from remote.
iv. Run composer install on server.
v. Don't forget to push your package to remote else, you will not see the changes on server, though you see on local.

What is usage of "conflict" in composer.json and what should I do with it?

I found the composer.json & composer.lock(php) has conflict section (not to be confused with merge conflict ). The other similar files like package.json/yarn.json (nodejs) or Pipfile (python) and the corresponding lock files package-lock.json/yarn.lock or Pipfile.lock, do not have such format even though all these lock files serve the same purpose (lock the dependence to the exact version) and implement in the similar way (at least looking from the surface)
So what is usage of it and what should I do with it ? I read the composer document https://getcomposer.org/doc/04-schema.md#conflict but I still feel confused, e.g.
Map of packages that conflict with this version of this package. They will not be allowed to be installed together with your package.
For example after running composer install I have a composer.lock saying
{
"name": "symfony/http-kernel",
"version": "v4.4.20",
...
"conflict": {
"symfony/browser-kit": "<4.3",
"symfony/config": "<3.4",
"symfony/console": ">=5",
"symfony/dependency-injection": "<4.3",
"symfony/translation": "<4.2",
"twig/twig": "<1.43|<2.13,>=2"
},
...
It is easy to guess "symfony/console" 5.0 is conflicted with "symfony/http-kernel" 4.4.20 so symfony/console 5.0 will not be installed.
Do I need to do anything with the conflict ? So far I feel like that as a package user (not the package developer) those info is just a FYI and I don't need to do anything. But then why bother to list them for me ? After all package.json and Pipefile don't have such information and I don't find the problem without it.
--- update ---
From the answer I got I realize I need to emphasize this: I understand composer.lock is for composer so I don't need to worry about it.
What I don't understand is the purpose putting it in composer.json, this file is for human users. So if it has a conflict section what should I do about it?
I want to know a practical use case of "conflict" section in my composer.json if I am not a package developer but a package user.
When building an application, you are free to choose your dependencies way better than when you are building a reusable library like symfony/http-kernel which you've mentioned in your question.
Putting any other package constraint in the conflict section of such a package means: if you want to install the package in the current version, no other package version must be installed that is listed in the conflict section. From your example: symfony/http-kernel in v4.4.20 must not be installed if symfony/browser-kit is installed in any version <4.3.
In your own application, you have more freedom to use stricter constraints for the packages you use. You could require all packages with pretty strict version numbers, but this makes updates less comfortable. For example, this is a part of the require section in one of my current projects:
"doctrine/annotations": "^1.0",
"doctrine/doctrine-bundle": "^2.2",
"doctrine/doctrine-migrations-bundle": "^3.0",
"doctrine/orm": "^2.7",
"easycorp/easyadmin-bundle": "^3.1",
"exercise/htmlpurifier-bundle": "^3.1",
"knplabs/knp-snappy-bundle": "^1.8",
"league/csv": "^9.6",
"lexik/jwt-authentication-bundle": "^2.10",
"nelmio/cors-bundle": "^2.1",
All these packages might install tons of other dependencies which I cannot control. But if I know that any version of the other dependencies causes trouble, I can list them in the conflict section of my application such that this version is not installed.
For example, in the past I've needed that for an update of doctrine/migrations where the configuration has changed. I wanted to be able to update all packages except this one, because I didn't want to bother with the configuration changes I had to apply to my application for a while.
"conflict": {
"symfony/console": ">=5",
this means that for some reason your package can't work with symfony/console version 5 and higher, so it will keep it below 5.
E.g. you can exclude some package faulty version:
"conflict": {
"foo/bar": "1.420.69",
}
I know this is an old post, but thought I'd add a point to what's already been said:
You may still benefit from a conflict section in composer.json if you know any of your code conflicts with any packages. It could be any reason from both your code and the package trying to do similar jobs and stepping on each other's toes or simply that a package is badly written and breaks your code.
In that case, you can add a conflict section in your composer.json to tell composer to never download that package (or some releases of it).
This would be useful if you work with other developers and someone else might try to require that package, or if you worry that composer may try to install it as a dependency of yet another package e.g. X is the package you don't want, but another package Y depends on X and you don't know. Without the conflict section, composer would download package X without you even knowing/noticing.

Composer: library which requires a library

I am trying to create a PHP library which includes other libraries, and I bet I'm missing something fundamental.
Using the AWS PHP SDK as a guide, I'd like to create a library which, after installing with Composer, requires other libraries, yet the entire scope of classes (both from the current library, and required libraries) all become available simply by using require 'vendor/autoload.php;'.
What are the basic requirements to set this up? Is it a matter of configuring composer.json, namespacing in a particular way, or both?
What you're describing is exactly Composer's main purpose - the definition of a package of code that may require and implement other packages.
Using the AWS SDK as a guide, if you look at the composer.json file, which provides all of the Composer configuration information, you'll see two require blocks, one labeled require and one labeled require-dev:
"require": {
"php": ">=5.5",
"guzzlehttp/guzzle": "^5.3.1|^6.2.1",
"guzzlehttp/psr7": "^1.4.1",
"guzzlehttp/promises": "~1.0",
"mtdowling/jmespath.php": "~2.2"
},
"require-dev": {
"ext-openssl": "*",
"ext-pcre": "*",
"ext-spl": "*",
"ext-json": "*",
"ext-dom": "*",
"ext-simplexml": "*",
"phpunit/phpunit": "^4.8.35|^5.4.0",
"behat/behat": "~3.0",
"doctrine/cache": "~1.4",
"aws/aws-php-sns-message-validator": "~1.0",
"nette/neon": "^2.3",
"andrewsville/php-token-reflection": "^1.4",
"psr/cache": "^1.0"
},
This is how you define what other packages/libraries your library depends upon. The require section lists all other libraries that must be installed when your library is installed. The require-dev section lists libraries that may only be necessary when you are working in a development environment, and are not needed in your production environment.
When you specify other libraries that are required, Composer will install your library, and then go out and also require the libraries your library requires (and then the libraries those libraries require, and so on and so on).
Also included with the libraries to include, you'll notice that the version numbers are also included, to ensure compatibility.
The easiest way to add new dependencies I find is on the command line, with the composer require command, documented here: https://getcomposer.org/doc/03-cli.md#require. The command helps you search for the package you want if you don't know it exactly, and can resolve the latest version for you automatically (which you can override if you need/want to).
If you wish to require a development-only dependency, add the --dev flag when running the command.
Using this command, Composer will automatically update your composer.json file, pull down the dependency onto the local machine, and update your autoloader.
You should never need to do anything more than require_once vendor/autoload.php to ensure dependencies can be autoloaded - Composer will do all the legwork of setting up the autoloader so you don't have to, and keep everything up to date as new dependencies are added.
Here's the complete documentation on the composer.json schema: https://getcomposer.org/doc/04-schema.md. You will want to have a composer.json config file in the root of project, so you can configure composer for your project (and any others that require your library later). If you don't have one, you can use the composer init command to interactively create one. Documentation on that command is available here: https://getcomposer.org/doc/03-cli.md#init
And here's their basic usage guide, in case you haven't gone through it already: https://getcomposer.org/doc/01-basic-usage.md

Composer Only Installs Packages w/ Manual Update to JSON File

When I use composer to install packages in my project I am only able to do so if I update my json file manually.
For example, if I run the following command in Git-Bash in my project directory (which contains my composer.phar and composer.json file):
php composer.phar require php-di/slim-bridge
It returns the following error:
[Invalid Argument Exception]
Could not find package
php-di\slim-bridge at any version for your minimum-stability (stable).
Check the package spelling or your minimum stability.
However, if i were to just update my json file to the following (example I've provided contains multiple packages I am using in my project):
{
"require": {
"slim/slim": "^3.0",
"slim/twig-view": "^2.1",
"illuminate/database": "^5.2",
"respect/validation": "^1.0",
"slim/csrf": "^0.6",
"slim/flash": "^0.1",
"phpmailer/phpmailer": "^5.2",
"php-di/slim-bridge":"^1.0"
},
"autoload":{
"psr-4": {
"App\\": "app"
}
}
}
... And I run the command: $ php.composer.phar update
Everything installs to project correctly.
What is going on that I am not able to install packages using the require method thus making me resort to manually updating my json file each time?
Since I am using windows, I used the windows installer for composer rather than install through command line and I got this working correctly. Much much easier now since I don't have to update my JSON files manually.

Local composer update fails with new heroku php buildpack

When moving from our own PHP custom buildpack to the supported Heroku one we are running into a problem. Heroku requires us to add certain extensions to the composer.json "require" part, but when you then try to update locally it fails because these packages do not exists in the repo.
Config file:
{
"config":{
"github-oauth":{
"github.com":""
}
},
"require": {
"php": "*",
"ext-newrelic": "*",
"ext-memcached": "*",
"aws/aws-sdk-php": "2.*",
"rollbar/rollbar": "*",
"yiisoft/yii": "1.1.15",
"cloudinary/cloudinary_php": "1.0.11",
"geoip/geoip": "v1.14",
"sendgrid/sendgrid": "2.1.1",
"swiftmailer/swiftmailer": "v5.2.1",
"crisu83/yiistrap": "dev-bs3"
},
"require-dev": {
"phpunit/phpunit": "3.7.*",
"phpunit/dbunit": ">=1.2",
"phpunit/php-invoker": "*",
"phpunit/phpunit-selenium": ">=1.2",
"phpunit/phpunit-story": "*",
"squizlabs/php_codesniffer": "1.*",
"phpmd/phpmd" : "1.4.*",
"phploc/phploc": "*",
"pdepend/pdepend" : "1.1.0",
"sebastian/phpcpd": "*",
"mayflower/php-codebrowser": "~1.1"
}
}
Error message:
11:08:55 {development} /Volumes/Development/web$ composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.
Problem 1
- The requested PHP extension ext-newrelic * is missing from your system.
Problem 2
- The requested PHP extension ext-memcached * is missing from your system.
Any ideas ?
You need to install those extensions. The assumption is that you develop, run and test your code locally during development using roughly the same components and environment as in production, so if you use memcache in production, you also use it locally. That ensures you're not running into nasty surprises because different datastores behave differently etc. Also see http://12factor.net/dev-prod-parity
Exception to the rule: you don't need to install the New Relic extension; it's enabled automatically on push if you provision the New Relic add-on (by detecting NEW_RELIC_LICENSE_KEY env var), see https://devcenter.heroku.com/articles/php-support#extensions (it is of little use locally on a developer's box, and can be a bit troublesome to install).
Installing the extensions fixed this for me (the newrelic extension is giving me trouble but that's another question.)
(Answer was posted here, but the person removed it again.)

Categories