Overview
Phalcon was originally written in C, which limited contributions because most PHP developers do not work in C. To make contributing approachable, the team introduced Zephir, a language with a syntax close to PHP and JavaScript that compiles to a PHP extension. The Phalcon codebase was rewritten in Zephir for Phalcon 2.0, and Zephir has been central to Phalcon’s development ever since.
The Challenge
Building a feature-rich framework requires a development environment with many services. Validating the ORM across database adapters (MySQL, PostgreSQL, SQLite) requires the relevant PHP extensions and databases. Running the full test suite requires more still, such as Redis and Memcached. Add the range of supported PHP versions (8.1 through 8.5), and a local setup becomes involved.
Solution
Phalcon previously used nanobox, which is now discontinued. The development environment is now built on Docker. A few commands bring up every service and PHP version needed to build the extension and run the tests.
Installation
Before you begin, install Docker. If you have not installed it yet, follow the instructions here. You will also need docker compose; installation details are here.
Running the Development Environment
1. Fork the repository. Fork the cphalcon repository to your GitHub account. Navigate to the cphalcon page and click the Fork button at the top right.
2. Clone the fork. Clone the forked repository to a directory of your choice. The example below assumes the GitHub account is niden; replace it with your own.
git clone [email protected]:niden/cphalcon3. Build the environment. Navigate to the cphalcon folder and build the containers:
docker compose buildThis may take some time, depending on your machine. It is not run frequently, only when the Dockerfiles change or you choose to rebuild.
Starting the Environment
Once the containers are built, start the environment:
docker compose up -dThe command uses the docker-compose.yml file from the repository and runs the environment in the background, so your terminal stays free. To stop the environment:
docker compose downService Networking
The service containers (databases, cache, queue) are not published to the host. They are reachable over the internal Compose network by their service name, for example mysql, mariadb, postgres, redis, memcached, and beanstalkd. You run the tests from inside a PHP development container, which reaches each service by that name. Because no host ports are published, you can run this environment alongside other projects without port collisions.
Entering the Environment
The environment provides one container per supported PHP version:
cphalcon-dev-8.1
cphalcon-dev-8.2
cphalcon-dev-8.3
cphalcon-dev-8.4
cphalcon-dev-8.5To enter the PHP 8.1 container:
docker exec -it cphalcon-dev-8.1 /bin/bashYou will be prompted with:
[email protected]:/srv#You are now inside the environment with the extensions and services available. To exit, type exit:
[email protected]:/srv# exitAliases
The development containers define aliases in the .bashrc under resources/docker/develop/. The most useful ones:
| Alias | Command |
|---|---|
g |
git |
h |
history |
l |
ls -lF |
zephir |
./vendor/bin/zephir |
zf |
./vendor/bin/zephir fullclean |
zg |
./vendor/bin/zephir generate |
zs |
./vendor/bin/zephir stubs |
cpl |
zf && zg && cd ext/ && ./install && cd .. |
Composer
Install the dependencies:
[email protected]:/srv# composer installComposer commands
Composer is configured to build and test the extension. Run a command with:
composer <command>For example:
# Run the code sniffer
composer csThe test scripts run through Talon, the Phalcon test runner (see below):
| Command | Description |
|---|---|
analyze |
Run Psalm static analysis |
cs |
Run CodeSniffer (phpcs) |
cs-fix |
Apply CodeSniffer fixes (phpcbf) |
cs-fixer |
Run PHP CS Fixer (dry run) |
cs-fixer-fix |
Apply PHP CS Fixer |
test-unit |
Run the unit suite (talon run unit) |
test-unit-coverage |
Run the unit suite with Clover coverage |
test-db-mysql |
Run the MySQL database suite |
test-db-pgsql |
Run the PostgreSQL database suite |
test-db-sqlite |
Run the SQLite database suite |
test-db |
Run all database suites (mysql, pgsql, sqlite) |
test-all |
Run every suite |
Check Zephir
Zephir is installed by Composer. Confirm it is available:
[email protected]:/srv# zephirCompile Phalcon
Compile the extension with Zephir using the cpl alias:
[email protected]:/srv# cplCheck Extensions
Verify the extension is loaded:
[email protected]:/srv# php -mCheck for phalcon in the list of installed modules.
Setup Databases
Create a .env file in the project root from the Docker template:
[email protected]:/srv# cp tests/support/_config/.env.docker .envTesting with Talon
Phalcon runs its suites through Talon, the Phalcon test runner. Talon is a harness over PHPUnit: it loads the correct Phalcon build, applies the suite configuration, and runs the tests. In cphalcon it loads the C extension you have compiled. The same runner is used across the Phalcon projects, on both the v5 C extension and the v6 phalcon/phalcon package, and Talon uses whichever is present.
Suites are declared in talon.php at the repository root. Each suite maps to a PHPUnit configuration under resources/:
| Suite | PHPUnit configuration |
|---|---|
unit |
resources/phpunit.xml.dist |
mysql |
resources/phpunit.mysql.xml |
pgsql |
resources/phpunit.pgsql.xml |
sqlite |
resources/phpunit.sqlite.xml |
Run a suite directly with:
[email protected]:/srv# ./vendor/bin/talon run unitThe Composer scripts wrap these calls, so composer test-unit runs talon run unit. For the full Talon reference, see the Talon page.
Running Tests
Unit
Run the unit suite:
[email protected]:/srv# composer test-unitRun a subset by passing PHPUnit arguments after --:
# a single test method by name
[email protected]:/srv# ./vendor/bin/talon run unit -- --filter testConnect
# a specific directory
[email protected]:/srv# ./vendor/bin/talon run unit -- tests/unit/<subdirectory>Database
Run the database suites:
[email protected]:/srv# composer test-db-mysql
[email protected]:/srv# composer test-db-pgsql
[email protected]:/srv# composer test-db-sqlite
[email protected]:/srv# composer test-dbCoverage
Generate a Clover coverage report for the unit suite:
[email protected]:/srv# composer test-unit-coverageDevelopment
Open your editor and develop in Zephir. After changing any .zep file (inside the phalcon folder), recompile the extension:
[email protected]:/srv# cplThen run the tests:
[email protected]:/srv# composer test-unitFor Zephir documentation, see the Zephir Docs.
Services
The available services are:
- Beanstalkd
- MariaDB
- Memcached
- MySQL
- PostgreSQL
- Redis (including a Redis Cluster)
Enabled PHP extensions include:
- apcu
- ctype
- curl
- dom
- fileinfo
- gd
- gettext
- gmp
- iconv
- igbinary
- imagick
- intl
- json
- mbstring
- memcached
- mongodb
- msgpack
- opcache
- pdo
- pdo_mysql
- pdo_pgsql
- pdo_sqlite
- phar
- redis
- session
- simplexml
- sqlite3
- tokenizer
- xdebug
- xml
- xmlwriter
- yaml
- zephir_parser
- zip
- zlib
Database schema dumps are located under tests/support/assets/db/schemas.
For questions, join the Discord server or our Discussions.
<3 Phalcon Team