PHP has played a crucial role in web development, and it was introduced into 4D v12 to offer features not readily available in the native language, such as zip, hash, or LDAP functionality. Over time, 4D has incorporated many of these PHP features into its core functionality. As a result, we decided to remove the built-in PHP interpreter in 4D v20 R3 and begin the deprecation process for PHP commands in v21.
While we won’t entirely remove the PHP commands from 4D, we strongly encourage you to use the system workers to execute PHP code in the future.
This blog post will guide you through this transition process, demonstrating how to use an external interpreter through PHP Execute and explaining how to execute PHP code effectively with a system worker.
First step: removal of the 4D built-in PHP interpreter
The first change will happen in 4D v20 R3 by removing the 4D built-in PHP interpreter. PHP Execute will continue to work but only with an external PHP interpreter. If you are unfamiliar with using an external PHP interpreter, please follow this tutorial.
Using PHP Execute with an external PHP interpreter
Using an external PHP interpreter will allow you to update any time you want to newer PHP versions and install security patches as soon as they are released. It also allows you to use more PHP modules.
Create a custom php.ini file
The php.ini file is used to initialize the PHP interpreter. This file was automatically created and used when calling PHP Execute with the internal interpreter. For the external interpreter, this file must be created and passed manually. Calling PHP Execute once will create the file in your project’s resources folder: we strongly suggest you use this file to initialize the external PHP interpreter, modifying it if necessary.
Run a CGI version of PHP.
There are 2 ways of running PHP: With a command line interface (CLI) or through the common gateway interface (CGI). PHP Execute uses the common gateway interface, so you must run a CGI version of PHP.
For Windows, you can download PHP on the official PHP website. This version contains both the CLI and CGI versions of PHP.
Currently, the version on the official website doesn’t load the mbstring package by default. To do so, you need to add these lines to the php.ini file:
extension_dir = "./ext/"
extension=mbstring
On Mac, this is a bit more complicated. Apple has stopped shipping macOS with PHP installed (for similar reasons, we stopped shipping one). The official PHP website does not provide a pre-built version for Mac. You might find pre-built versions on some sites, but usually, they are not maintained or recommended. To help you transition, 4D provides its 4D v20 built-in PHP as a separate binary on the product download page. Note that this binary won’t be maintained by 4D. If you need to upgrade PHP on a Mac in the future, you will have to build your own. I’ll detail how to do so later in this blog post.
You then need to launch PHP through the terminal by calling this command inside the PHP directory:
On Windows:
php-cgi -b <address:port> -c <path_to_php.ini_file_inside_the_project_resources_folder>
On Mac:
./php-cgi -b <address:port> -c <path_to_php.ini_file_inside_the_project_resources_folder>
Or if you use the 4Dv20 built-in PHP:
On Windows:
php-fcgi-4d -b <address:port> -c <path_to_php.ini_file_inside_the_project_resources_folder>
On Mac:
./php-fcgi-4d -b <address:port> -c <path_to_php.ini_file_inside_the_project_resources_folder>
Don’t forget, when you type a path, to escape special characters (like \ and “) by adding a \ just before (\\ and \”).
As you need to run PHP on the same machine as 4D, the address must be 127.0.0.1. PHP default port is 8002, which is also the default port 4D uses. We encourage you to use the system workers to start and stop PHP so you don’t need to run it manually.
For example, to run PHP with a system worker, you can use this code:
var worker : 4D.SystemWorker
worker:=4D.SystemWorker.new("<path_to_php_cgi_executable> -b <address:port> -c <path_to_php.ini_file_inside_the_project_resources_folder>")
And later terminate PHP with:
worker.terminate()
Configure 4D settings to connect to your external PHP
Open the PHP tab of the structure settings and enter your PHP server’s IP address and port. Then, reopen your project.
Default options of the PHP tab of the structure settings.
8002 is the default PHP port, and as the PHP server needs to run on the same machine as 4D, you need to use the 127.0.0.1 address.
Call PHP Execute
Now that your PHP server is started and 4D properly configured, you can use PHP Execute with the same syntax you used in the past. No need to change anything in your code as long as you use 4D v20 R3 or newer. To use the above-explained concept in older versions, use SET DATABASE PARAMETER(PHP use an external interpreter;1) – which is now the default setting for 4D. Note that the same command allows you to set PHP IP or port by code if you don’t want to set it via interface, as explained above.
Second step: Deprecation of PHP Execute
The second change will happen for 4D v21: the deprecation of PHP Execute. The command will stay functional, and we don’t intend to remove it from 4D. If you decide to use PHP in your application in the future, using the system workers to run your PHP code is strongly advised.
Using system workers to run PHP code
Install or build PHP
On Windows, you can download PHP on the official PHP website.
On Mac, you will need to build PHP as a 4D built-in PHP interpreter that only comes with the fast CGI version, while you will need the CLI version of PHP. I’ll detail how to do it later in this blog post.
Call PHP with system workers.
Let me give you 2 examples of how to execute your PHP code with system workers.
The first example interprets a PHP file and retrieves the output in the $result variable.
var $worker : 4D.SystemWorker
var $result : Text
$worker:=4D.SystemWorker.new("<path_to_php_executable> -f <path_to_php_file> -c <path_to_php.ini_file_inside_the_project_resources_folder>")
$result:=$worker.wait().response
The second example runs PHP as an interactive shell, so we can ask it to interpret directly some PHP code. This way of executing PHP code is more optimized if you have to make many PHP calls, as you only start PHP once.
var $worker : 4D.SystemWorker
var data : Text
//The onData callback will append the result of the execution to the data variable
var $options : Object
var $onData : 4D.Function
$onData:=Formula(data+=$2.data)
$options:=New object("onData"; $onData)
$worker:=4D.SystemWorker.new("<path_to_php_executable> -a -c <path_to_php.ini_file_inside_the_project_resources_folder>"; $options)
$worker.wait(1)
data:=""
$worker.postMessage("echo \"Hello World!\";\r\n")
$worker.wait(1)
$worker.terminate()
The result of the execution is retrieved in the data variable, in this case, Hello World!
Getting PHP on Mac
The simplest solution to retrieve PHP on Mac is to use Homebrew. Unfortunately, it will only get PHP on your machine, and you won’t be able to distribute it. If you want to distribute PHP with your application, you must compile it.
Using Homebrew to build PHP
Install Homebrew
You can find a package to install Homebrew on GitHub.
Otherwise, you can install it via the terminal. First, you’ll need Xcode tools. Call this command to install them:
xcode-select --install
You can then install Homebrew with this command:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
Install PHP
You can then install PHP with this command:
brew install php
Compiling PHP on Mac
If you need to distribute your 4D application on Mac, you’ll need an embedded version of PHP. To create it, you need to compile one. Here is the complete procedure to do so:
Install Homebrew
To install Homebrew, you’ll need Xcode tools. Call this command to install them:
xcode-select --install
You can then install Homebrew with this command:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
Install utility programs
To compile PHP, you’ll need both groff and pkg-config. You can install them by using these commands:
brew install groff
brew install pkg-config
Compile the OpenLDAP library
Download the OpenLDAP library.
Extract the content of the compressed file:
tar -zxf <name_of_the_archive>
You then need to compile the OpenLDAP library. You need a destination folder for the compiled library.
Go to the OpenLDAP folder and configure for installation:
./configure --prefix="<path_of_the_destination_folder>" --disable-backends --enable-ldap --without-fetch --without-cyrus-sasl --enable-shared=no --enable-static=yes
Compile dependencies:
make depend
Compile the library:
make
Install in the destination folder:
make install
Compile the OpenSSL library
Download the OpenSSL library.
Extract the content of the compressed file:
tar -zxf <name_of_the_archive>
You then need to compile the OpenSSL library. You need a destination folder for the compiled library, choose a different folder than the OpenLDAP one.
Go to the OpenSSL folder and configure for installation:
./config --prefix="<path_of_the_destination_folder>"
Compile the library:
make
Install in the destination folder:
make install
Compile PHP
Download PHP.
Extract the content of the compressed file:
tar -zxf <name_of_the_archive>
You then need to compile the PHP. You need a destination folder for PHP, choose a different folder than the OpenLDAP one.
Go to the PHP folder and configure for installation:
./configure --prefix="<path_of_the_destination_folder>" --disable-all --enable-cgi --enable-shared=no --enable-static=yes --with-openssl="<path_of_the_OpenSSL_destination_folder>" --with-ldap="<path_of_the_OpenLDAP_destination_folder>" --enable-bcmath --enable-calendar --enable-exif --enable-ftp --enable-mbstring --disable-mbregex --enable-sockets --with-sqlite3 --disable-posix --enable-ctype --enable-fileinfo --enable-filter --enable-pdo --with-pdo-sqlite --enable-phar --enable-session --enable-tokenizer --disable-opcache
Compile the library:
make
Install in the destination folder:
make install
Inside the PHP destination folder, you’ll find both a fast CGI version of PHP and a CLI version of PHP. The fast CGI version can be used as an external PHP server with PHP Execute. The CLI version can be used with the system workers.
Use the forum if you have any questions
We want to ensure your transition is as smooth as possible. We understand that it may require some effort, and we are here to assist you every step of the way. Please don’t hesitate to reach out to our forum with any questions or comments; we’re more than happy to provide answers and guidance.
If you decide to start a new discussion about PHP on the forum, please remember to include the “PHP” tag. This will make it easier for everyone to locate and engage with your topic.