Hello world ᴾᴴᴾ - chung-leong/zigar GitHub Wiki
JavaScript | PHP
In this example we're going to create a very simple server-side app that outputs "Hello world!" to the console through Zig. It demonstrates the basics of working with php-zigar and the steps for deploying an app in different server environments.
Make sure you have activate the php-zigar extension in php.ini before you begin.
Creating the sample app
First, create an new directory for the project:
mkdir hello
Create one directory for PHP files and another for Zig files:
cd hello
mkdir src zig
In a text editor, create hello.zig in zig:
const std = @import("std");
pub fn hello() void {
std.debug.print("Hello world!", .{});
}
Followed by hello.php in src:
<?php
$m = zigar_use(__DIR__ . '/../zig/hello.zig');
$m->hello();
Then run it:
php src/hello.php
A message will appear informing you that the module "hello" is being built. After 30 seconds or so, the following should appear in the terminal:
Hello world!
At this point, you'll notice that a lib sub-directory has been added to hello. Within it,
you'll see a sub-directory named hello.zigar. This is the Zigar module. The directory can
contain multiple dynamically linked libraries, each targetting a specific platform. For now,
you'll only see the one created for your computer, either linux.x64.so or win32.x64.dll.
When zigar_use() is given a path to a zig file, it'll both compile and load the module. The
setting zigar.module_rel_path determines where the module will be
placed relative to the source file. By default it's /../lib.
You can use zigar_compile() to create the module at an abitrary location:
<?php
zigar_compile(__DIR__ . '/../zig/hello.zig', '/tmp/zig-stuff/turkey');
$m = zigar_use('/tmp/zig-stuff/turkey');
$m->hello();
Importing functions and classes
zigar_use() keeps Zig functions and classes within the object that it returns. You can make these
functions and classes appear in the global PHP namespace by using zigar_import() instead:
<?php
$m = zigar_import(__DIR__ . '/../zig/hello.zig');
$m->hello();
hello();
Hello world!
Hello world!
Doing so will prevent the module from getting garbage-collected until the request finishes.
zigar_import() accepts a callback function as its second argument which allows you to customize
the names of the imported symbols:
<?php
$m = zigar_import(__DIR__ . '/../zig/hello.zig', function($name, $type) {
return "cow_{$name}_${type}";
});
cow_hello_function();
Configuring the app for deployment
If you're a Windows or Mac user, shared libraries created during development will most likely
not work in your eventual production environment. Moreover, they're compiled at the Debug
optimization level, meaning they are both slow and needlessly large. To make the module a production-ready module, you need a build script.
In your editor, create build.php in src:
<?php
$targets = [
[ 'platform' => 'linux', 'arch' => 'x64' ],
[ 'platform' => 'linux', 'arch' => 'arm64' ],
[ 'platform' => 'darwin', 'arch' => 'arm64' ],
[ 'platform' => 'win32', 'arch' => 'x64' ],
];
foreach ($targets as $options) {
zigar_compile(__DIR__ . '/../zig/hello.zig', $options);
}
Note: possible values for platform and arch are listed in the documentation for
Node.js's os.platform() and
os.arch().
Before you run the script, open php.ini and change the optimization setting:
[zigar]
zigar.optimize=ReleaseSmall
You can also specify the optimization level in the options array passed to zigar_compile().
Setting it in php.ini ensures that you wouldn't unintentionally overwrite the production-ready
library with a debug version.
After build.php is done running, the directory structure of hello should look like this:
📁 hello
📁 lib
📁 hello.zigar
📑 darwin.arm64.dynlib
📑 linux.arm64.so
📑 linux.x64.so
📑 win32.x64.dll
📑 win32.x64.pdb
📁 src
📁 zig
The module is now ready to be used in nearly any production environment. Provided, of course, that php-zigar is installed on the server.
The server's copy of php.ini should contain the following:
[zigar]
zigar.recompile=Off
This will stop php-zigar from attempting to recompile the module.
Source code
You can find the complete source code for this example here.
Conclusion
You have just learned the basics of using php-zigar in server-side applications. The app we created doesn't do much. In the next example we're going to create an app that actually does something useful.