QIQ (Quick Interpreter for Quasi-PHP, /kik/) is an implementation of the PHP language specification written in the Go programming language.
The goals of the project are:
- Deep dive into the PHP language syntax and the internals of its mode of operation
- Gain more experience in writing lexers, parser and interpreter
- Very long-term goal: Implement as many parts of the standard library and language features as needed to run a simple Laravel application 😓
More documentation:
Usage of ./qiq:
-h Show help.
-debug Enable debug mode (for development on QIQ).
-dev Run in developer mode.
-stats Show statistics.
-S string Run with built-in web server. <addr>:<port>
-t string Specify document root <docroot> for built-in web server.
-f string Parse and execute <file>.
-ini string Path to ini file to use.
-create-ini string Create given ini file.
Parse file:
cat index.php | ./qiq or ./qiq -f index.php
Run web server:
./qiq -S localhost:8080 - Document root is current working directory
./qiq -S localhost:8080 -dev - Web server in developer mode
./qiq -S localhost:8080 -t /srv/www/html - Document root is /srv/www/html
There are a lot of test cases in the source repository for PHP under the folder tests.
In order to test the QIQ implementation against this cases the binary qiqTester can be used.
Usage:
./qiqTester [-h] [-v(1|2)] [-only-failed] [-no-color] [-replace-json <file-name>] <list of directory or phpt-file>Examples:
./qiqTester php-src/tests
./qiqTester -v2 php-src/tests/basic/001.phptIf you want to test or use QIQ with Docker, we've got you covered!
You can use the latest version: (This is not recommended as it might by unstable):
docker pull ghcr.io/masterzydra/qiq:latestOr use a specific version:
docker pull ghcr.io/masterzydra/qiq:v0.4.0You can find all versions here.
docker run -p 8080:8080 ghcr.io/masterzydra/qiq:latestYou can change the port used inside the container (default: 8080):
docker run -p 8081:8081 --env PORT=8081 ghcr.io/masterzydra/qiq:latestYou can change the document root (default: /var/www/html)
docker run -p 8080:8080 --env DOC_ROOT=/var/www/html/public ghcr.io/masterzydra/qiq:latestYou can run the QIQ server in development mode (default: false)
docker run -p 8080:8080 --env DEV=true ghcr.io/masterzydra/qiq:latestYou can also mount a local project into the container:
docker run -p 8080:8080 -v $(pwd):/var/www/html:z ghcr.io/masterzydra/qiq:latestIn addition to supporting official PHP syntax and features, QIQ offers some unique capabilities:
QIQ provides the qiq.case_sensitive_include INI directive, which enforces case-sensitive behavior for include and require statements even on Windows systems. This helps catch issues where file or path casing does not match, which would otherwise only cause problems in Linux environments.
QIQ provides the qiq.strict_comparison INI directive, which enforces strict comparison semantics throughout your codebase. When enabled, the == operator behaves like ===, and both != and <> behave like !==. This can help to prevent subtle bugs caused by type juggling in comparisons, making the code more predictable and robust.
The application loads configuration files in the following order:
- The INI file
qiq.inilocated in the same directory as the executable. - The INI file
qiq.inilocated in the document root. - Any custom INI file specified by the user using the
-iniflag.
You can generate a new INI file using the -create-ini flag:
qiq -create-ini <path>/qiq.iniFor some part of this project, the following resources were used as a guide, inspiration, or concept:
- PHP Language Specification
- YouTube playlist Build a Custom Scripting Language In Typescript by tylerlaceby
- Book Crafting Interpreters by Robert Nystorm
- Book Writing An Interpreter In Go by Thorsten Ball