I am working on a small PHP library that should use some new features from PHP 7, for example scalar type declarations and return type declarations. But my current Debian 8 has only PHP 5.6.29 for me at the moment. The unstable distribution sid is no option to me and in general I try to avoid installing a specific PHP interpreter on my OS. Fortunately I need PHP only on the command line to test my library so I can use Docker to switch between the versions.
Let us start with a PHP 7 only Hello World script. The first argument on the command line will be appended to the
string Hello
. The script will append the string PHP
if there is no first argument.
<?php
function hello(string $name) : string
{
return "Hello " . $name . "\n";
}
$name = $argv[1] ?? "PHP";
echo hello($name);
As expected is the PHP 5.6 interpreter on my operating system not able to parse this PHP code.
php HelloWorld.php
PHP Parse error: syntax error, unexpected ':', expecting '{' in HelloWorld.php on line 3
Let us run the same PHP script in the PHP Docker container with PHP 7.1.
docker run -it --rm -v "$PWD"/HelloWorld.php:/HelloWorld.php php:7.1-cli php /HelloWorld.php Docker
Hello Docker
We will expand the minimal Hello World example from above with some dependencies that should be installed via Compsoer. The current project tree looks like this.
.
|-- vendor/
|-- composer.json
`-- HelloWorld.php
With a minimal composer.json
that is requiring
symfony/console.
{
"require": {
"php": "~7.0",
"symfony/console": "^3.2"
}
}
We do not need to install composer on our operating system, there is a Composer Docker container. The following command will install our dependencies.
docker run --rm -u $UID -v "$PWD":/app composer/composer install
Cannot create cache directory /composer/cache/repo/https---packagist.org/, or directory is not writable. Proceeding without cache
Cannot create cache directory /composer/cache/files/, or directory is not writable. Proceeding without cache
Loading composer repositories with package information
Updating dependencies (including require-dev)
- Installing psr/log (1.0.2)
Downloading: 100%
- Installing symfony/debug (v3.2.2)
Downloading: 100%
- Installing symfony/polyfill-mbstring (v1.3.0)
Downloading: 100%
- Installing symfony/console (v3.2.2)
Downloading: 100%
symfony/console suggests installing symfony/event-dispatcher ()
symfony/console suggests installing symfony/filesystem ()
symfony/console suggests installing symfony/process ()
Writing lock file
Generating autoload files
I have changed the HelloWorld.php
script to use the symfony/console. The script is mostly doing the
same thing as before.
<?php
require __DIR__.'/vendor/autoload.php';
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
function hello(string $name) : string
{
return "Hello " . $name . "\n";
}
(new Application('hello', '1.0.0'))
->register('hello')
->addArgument('name', InputArgument::OPTIONAL, 'The name')
->setCode(function(InputInterface $input, OutputInterface $output) {
$name = $input->getArgument('name') ?? "PHP";
$output->write(hello($name));
})
->getApplication()
->setDefaultCommand('hello', true)
->run();
The single PHP script command from above is producing the following error now.
docker run -it --rm -v "$PWD"/HelloWorld.php:/HelloWorld.php php:7.1-cli php /HelloWorld.php Docker
Warning: require(//vendor/autoload.php): failed to open stream: No such file or directory in /HelloWorld.php on line 2
Fatal error: require(): Failed opening required '//vendor/autoload.php' (include_path='.:/usr/local/lib/php') in /HelloWorld.php on line 2
So we need to include the hole project folder into the the Docker container like the following command is doing.
docker run -it --rm -v "$PWD":/usr/src/hello -w /usr/src/hello php:7.1-cli php HelloWorld.php Docker
Hello Docker