<commit_before># Testing PHP projects

This guide covers basic building instructions for PHP projects.

There are covered two cases: testing using the Docker executor and testing
using the Shell executor.

## Test PHP projects using the Docker executor

While it is possible to test PHP apps on any system, this would require manual
configuration from the developer. To overcome this we will be using the
official [PHP docker image][php-hub] that can be found in Docker Hub.

This will allow us to test PHP projects against different versions of PHP.
However, not everything is plug 'n' play, you still need to onfigure some
things manually.

As with every build, you need to create a valid `.gitlab-ci.yml` describing the
build environment.

Let's first specify the PHP image that will be used for the build process
(you can read more about what an image means in the Runner's lingo reading
about [Using Docker images](../docker/using_docker_images.md#what-is-image)).

Start by adding the image to your `.gitlab-ci.yml`:

```yaml
image: php:5.6
```

The official images are great, but they lack a few useful tools for testing.
We need to first prepare the build environment. A way to overcome this is to
create a script which installs all prerequisites prior the actual testing is
done.

Let's create a `ci/docker_install.sh` file in the root directory of our
repository with the following content:

```bash
#!/bin/bash

# We need to install dependencies only for Docker
[[ ! -e /.dockerinit ]] && exit 0

set -xe

# Install git (the php image doesn't have it) which is required by composer
apt-get update -yqq
apt-get install git -yqq

# Install phpunit, the tool that we will use for testing
curl -o /usr/local/bin/phpunit https://phar.phpunit.de/phpunit.phar
chmod +x /usr/local/bin/phpunit

# Install mysql driver
# Here you can install any other extension that you need
docker-php-ext-install pdo_mysql
```

You might wonder what `docker-php-ext-install` is. In short, it is a script
provided by the official php docker image that you can use to easilly install
extensions. For more information read the the documentation at
<https://hub.docker.com/_/php/>.

Now that we created the script that contains all prerequisites for our build
environment, let's add it in `.gitlab-ci.yml`:

```yaml
...

before_script:
- bash ci/docker_install.sh > /dev/null

...
```

Last step, run the actual tests using `phpunit`:

```yaml
...

test:app:
  script:
  - phpunit --configuration phpunit_myapp.xml

...
```

Finally, commit your files and push them to GitLab to see your build succeeding
(or failing).

The final `.gitlab-ci.yml` should look similar to this:

```yaml
# Select image from https://hub.docker.com/_/php/
image: php:5.6

before_script:
# Install dependencies
- ci/docker_install.sh > /dev/null

test:app:
  script:
  - phpunit --configuration phpunit_myapp.xml
```

### Test against different PHP versions in Docker builds

Testing against multiple versions of PHP is super easy. Just add another job
with a different docker image version and the runner will do the rest:

```yaml
before_script:
# Install dependencies
- ci/docker_install.sh > /dev/null

# We test PHP5.6
test:5.6:
  image: php:5.6
  script:
  - phpunit --configuration phpunit_myapp.xml

# We test PHP7.0 (good luck with that)
test:7.0:
  image: php:7.0
  script:
  - phpunit --configuration phpunit_myapp.xml
```

### Custom PHP configuration in Docker builds

There are times where you will need to customise your PHP environment by
putting your `.ini` file into `/usr/local/etc/php/conf.d/`. For that purpose
add a `before_script` action:

```yaml
before_script:
- cp my_php.ini /usr/local/etc/php/conf.d/test.ini
```

Of course, `my_php.ini` must be present in the root directory of your repository.

## Test PHP projects using the Shell executor

The shell executor runs your builds in a terminal session on your server.
Thus, in order to test your projects you first need to make sure that all
dependencies are installed.

For example, in a VM running Debian 8 we first update the cache, then we
install `phpunit` and `php5-mysql`:

```bash
sudo apt-get update -y
sudo apt-get install -y phpunit php5-mysql
```

Next, add the following snippet to your `.gitlab-ci.yml`:

```yaml
test:app:
  script:
  - phpunit --configuration phpunit_myapp.xml
```

Finally, push to GitLab and let the tests begin!

### Test against different PHP versions in Shell builds

The [phpenv][] project allows you to easily manage different versions of PHP
each with its own config. This is specially usefull when testing PHP projects
with the Shell executor.

You will have to install it on your build machine under the `gitlab-runner`
user following [the upstream installation guide][phpenv-installation].

Using phpenv also allows to easily configure the PHP environment with:

```
phpenv config-add my_config.ini
```

### Install custom extensions

Since this is a pretty bare installation of the PHP environment, you may need
some extensions that are not currently present on the build machine.

To install additional extensions simply execute:
<commit_msg>Add note about the various phpenv tools<commit_after># Testing PHP projects

This guide covers basic building instructions for PHP projects.

There are covered two cases: testing using the Docker executor and testing
using the Shell executor.

## Test PHP projects using the Docker executor

While it is possible to test PHP apps on any system, this would require manual
configuration from the developer. To overcome this we will be using the
official [PHP docker image][php-hub] that can be found in Docker Hub.

This will allow us to test PHP projects against different versions of PHP.
However, not everything is plug 'n' play, you still need to onfigure some
things manually.

As with every build, you need to create a valid `.gitlab-ci.yml` describing the
build environment.

Let's first specify the PHP image that will be used for the build process
(you can read more about what an image means in the Runner's lingo reading
about [Using Docker images](../docker/using_docker_images.md#what-is-image)).

Start by adding the image to your `.gitlab-ci.yml`:

```yaml
image: php:5.6
```

The official images are great, but they lack a few useful tools for testing.
We need to first prepare the build environment. A way to overcome this is to
create a script which installs all prerequisites prior the actual testing is
done.

Let's create a `ci/docker_install.sh` file in the root directory of our
repository with the following content:

```bash
#!/bin/bash

# We need to install dependencies only for Docker
[[ ! -e /.dockerinit ]] && exit 0

set -xe

# Install git (the php image doesn't have it) which is required by composer
apt-get update -yqq
apt-get install git -yqq

# Install phpunit, the tool that we will use for testing
curl -o /usr/local/bin/phpunit https://phar.phpunit.de/phpunit.phar
chmod +x /usr/local/bin/phpunit

# Install mysql driver
# Here you can install any other extension that you need
docker-php-ext-install pdo_mysql
```

You might wonder what `docker-php-ext-install` is. In short, it is a script
provided by the official php docker image that you can use to easilly install
extensions. For more information read the the documentation at
<https://hub.docker.com/_/php/>.

Now that we created the script that contains all prerequisites for our build
environment, let's add it in `.gitlab-ci.yml`:

```yaml
...

before_script:
- bash ci/docker_install.sh > /dev/null

...
```

Last step, run the actual tests using `phpunit`:

```yaml
...

test:app:
  script:
  - phpunit --configuration phpunit_myapp.xml

...
```

Finally, commit your files and push them to GitLab to see your build succeeding
(or failing).

The final `.gitlab-ci.yml` should look similar to this:

```yaml
# Select image from https://hub.docker.com/_/php/
image: php:5.6

before_script:
# Install dependencies
- ci/docker_install.sh > /dev/null

test:app:
  script:
  - phpunit --configuration phpunit_myapp.xml
```

### Test against different PHP versions in Docker builds

Testing against multiple versions of PHP is super easy. Just add another job
with a different docker image version and the runner will do the rest:

```yaml
before_script:
# Install dependencies
- ci/docker_install.sh > /dev/null

# We test PHP5.6
test:5.6:
  image: php:5.6
  script:
  - phpunit --configuration phpunit_myapp.xml

# We test PHP7.0 (good luck with that)
test:7.0:
  image: php:7.0
  script:
  - phpunit --configuration phpunit_myapp.xml
```

### Custom PHP configuration in Docker builds

There are times where you will need to customise your PHP environment by
putting your `.ini` file into `/usr/local/etc/php/conf.d/`. For that purpose
add a `before_script` action:

```yaml
before_script:
- cp my_php.ini /usr/local/etc/php/conf.d/test.ini
```

Of course, `my_php.ini` must be present in the root directory of your repository.

## Test PHP projects using the Shell executor

The shell executor runs your builds in a terminal session on your server.
Thus, in order to test your projects you first need to make sure that all
dependencies are installed.

For example, in a VM running Debian 8 we first update the cache, then we
install `phpunit` and `php5-mysql`:

```bash
sudo apt-get update -y
sudo apt-get install -y phpunit php5-mysql
```

Next, add the following snippet to your `.gitlab-ci.yml`:

```yaml
test:app:
  script:
  - phpunit --configuration phpunit_myapp.xml
```

Finally, push to GitLab and let the tests begin!

### Test against different PHP versions in Shell builds

The [phpenv][] project allows you to easily manage different versions of PHP
each with its own config. This is specially usefull when testing PHP projects
with the Shell executor.

You will have to install it on your build machine under the `gitlab-runner`
user following [the upstream installation guide][phpenv-installation].

Using phpenv also allows to easily configure the PHP environment with:

```
phpenv config-add my_config.ini
```

*__Important note:__ It seems `phpenv/phpenv`
 [is abandoned](https://github.com/phpenv/phpenv/issues/57). There is a fork
 at [madumlao/phpenv](https://github.com/madumlao/phpenv) that tries to bring
 the project back to life. [CHH/phpenv](https://github.com/CHH/phpenv) also
 seems like a good alternative. Picking any of the mentioned tools will work
 with the basic phpenv commands. Guiding you to choose the right phpenv is out
 of the scope of this tutorial.*

### Install custom extensions

Since this is a pretty bare installation of the PHP environment, you may need
some extensions that are not currently present on the build machine.

To install additional extensions simply execute:

{'fraction_non_alphanumeric': 0.07957189390414146, 'fraction_numerical': 0.003908794788273616, 'mean_word_length': 4.059322033898305, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 11, 'https://': 9, 'lorem ipsum': 0, 'www.': 0, 'xml': 10}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2063123', 'n_tokens_mistral': 3246, 'n_tokens_neox': 3036, 'n_words': 1483}