Building FunctionGraph HTTP Functions with PHP from scratch¶
Following chapter describes in short how to build FunctionGraph HTTP functions using PHP from scratch.
Introduction¶
For general details about creating HTTP functions from scratch and executing an HTTP function, see Creating a Function from Scratch and Executing the Function in the User Guide.
Function Development Overview¶
See also General Constraints for HTTP Functions
Step 1: Create a function¶
In FunctionGraph console, create a function with the following parameters:
Create with: Create from scratch
Function Type: HTTP Function
Region: select the region where you want to create the function
Function Name: http-function-scratch
leave the other parameters with default values, and click Create Function to create the function.
Step 2: Write code for the function¶
For HTTP functions, the code is expected to listen for HTTP requests and send responses.
You can use any PHP web framework or library to implement the function code.
The following is a sample code using the PHP built-in HTTP Web Server.
Full code for this example can be found at: samples-doc/scratch-http.
Note
This sample is for demonstration purposes only. The built-in Web Server should not be used on a public network.
In the code editor, replace the default code for file index.php with the following code, and click Deploy to save the code.
<?php
// Function to retrieve FunctionGraph environment variable values
// from the RUNTIME_USERDATA environment variable.
// $name is the key of the FunctionGraph environment variable to retrieve.
function getUserData($name) {
$userdata = getenv('RUNTIME_USERDATA');
if ($userdata === false) {
return null;
}
$runtime_userdata = json_decode($userdata, true);
return $runtime_userdata[$name] ?? null;
}
// Parse the request path from the URL.
$path = parse_url($_SERVER['REQUEST_URI'] ?? '/', PHP_URL_PATH);
$headers = getallheaders();
$request_id = $headers['X-Cff-Request-Id'] ?? null;
error_log("Request ID: " . $request_id, 4);
// Handle GET requests to the root path.
if ($_SERVER['REQUEST_METHOD'] === 'GET' && $path === '/') {
header('Content-Type: application/json');
$name = $_GET['name'] ?? 'World';
if (is_array($name)) {
$name = reset($name);
}
echo json_encode([
'message' => "Hello, {$name}!",
'user_data' => getUserData('USER_DATA'),
'secret_user_data' => getUserData('SECRET_USER_DATA'),
], JSON_THROW_ON_ERROR);
exit;
}
// Handle POST requests to the root path.
if ($_SERVER['REQUEST_METHOD'] === 'POST' && $path === '/') {
echo file_get_contents('php://input');
exit;
}
// Handle requests to paths that are not found.
http_response_code(404);
// Respond with a 404 status code and appropriate message for not found paths.
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
header('Content-Type: application/json');
echo json_encode(['message' => 'Not found!'], JSON_THROW_ON_ERROR);
} else {
echo 'Not Found';
}
Step 3: Configure the bootstrap file¶
A file named bootstrap is used to start the function runtime and execute the function code.
The following is the code to be added in the bootstrap file for PHP runtime.
It starts PHP built-in Webserver and executes the index.php file.
cd $RUNTIME_CODE_ROOT/src
/opt/function/runtime/[PHP_RUNTIME]/rtsp/php/bin/php -S 0.0.0.0:8000 [FUNCTION_FILENAME]
where
[PHP_RUNTIME] is the PHP runtime to use (see Supported PHP Runtimes).
$RUNTIME_CODE_ROOT is the environment variable that points to the root directory of your function code (/opt/function/code).
[FUNCTION_FILENAME] is the name of the file that contains your function code (e.g., index.php).
In the code editor, replace the default code for file bootstrap with the following code, and click Deploy to save the code.
cd $RUNTIME_CODE_ROOT
/opt/function/runtime/php8.3/rtsp/php/bin/php -S 0.0.0.0:8000 index.php
Step 4: Configure environment variables¶
Click on Configuration tab and then select Environment Variables to configure the environment variables for the function (see also Configuring Environment Variables in the User Guide)
Key |
Value |
Encrypted |
USER_DATA |
mydata |
disabled |
SECRET_USER_DATA |
mysecret |
enabled |
Note
Encrypted environment variables are only accessible through the runtime environment variable RUNTIME_USERDATA. The environment variable RUNTIME_USERDATA is a JSON string that contains all configured FunctionGraph environment variables and their values.
Step 5: Create test events¶
Click on Test tab, and click Configure Test Event to create test events with the following parameters:
(For HTTP functions only “API Gateway (Dedicated)” event template is supported.)
Execution event: test_post¶
For POST / request create a test event named test_post:
{
"body": "eyJtZXNzYWdlIjogIkhlbGxvLCBXb3JsZCEifQ==",
"requestContext": {
"apiId": "bc1dcffd-aa35-474d-897c-d53425a4c08e",
"requestId": "11cdcdcf33949dc6d722640a13091c77",
"stage": "RELEASE"
},
"queryStringParameters": {
"responseType": "html"
},
"httpMethod": "POST",
"pathParameters": {},
"headers": {
"content-type": "application/json",
"accept-language": "q=0.5,en-US;q=0.3,en;q=0.2",
"accept-encoding": "gzip, deflate, br",
"x-forwarded-port": "443",
"x-forwarded-for": "103.218.216.98",
"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"upgrade-insecure-requests": "1",
"host": "host",
"x-forwarded-proto": "https",
"pragma": "no-cache",
"cache-control": "no-cache",
"x-real-ip": "103.218.216.98",
"user-agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0"
},
"path": "/",
"isBase64Encoded": true
}
Execution event: test_get¶
For GET / request create a test event named test_get:
{
"body": "",
"requestContext": {
"apiId": "bc1dcffd-aa35-474d-897c-d53425a4c08e",
"requestId": "11cdcdcf33949dc6d722640a13091c77",
"stage": "RELEASE"
},
"queryStringParameters": {
"responseType": "html",
"name": "John"
},
"httpMethod": "GET",
"pathParameters": {},
"headers": {
"accept-language": "q=0.5,en-US;q=0.3,en;q=0.2",
"accept-encoding": "gzip, deflate, br",
"x-forwarded-port": "443",
"x-forwarded-for": "103.218.216.98",
"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"upgrade-insecure-requests": "1",
"host": "host",
"x-forwarded-proto": "https",
"pragma": "no-cache",
"cache-control": "no-cache",
"x-real-ip": "103.218.216.98",
"user-agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0"
},
"path": "/",
"isBase64Encoded": true
}
Step 5: Test the function¶
Click Test to execute the function with the test events created in the previous step,
and you should see the following output in the Execution Result section
Execution result: test_post¶
{
"body": "eyJtZXNzYWdlIjogIkhlbGxvLCBXb3JsZCEifQ==",
"headers": {
"Content-Type": [
"text/html; charset=UTF-8"
],
"Date": [
"Wed, 09 Sep 2026 10:27:22 GMT"
],
"Host": [
"host"
],
"X-Powered-By": [
"PHP/8.3.6"
]
},
"statusCode": 200,
"isBase64Encoded": true
}
The body in the output is base64 encoded. After decoding, you should see the following content:
{"message": "Hello, World!"}
Execution result: test_get¶
{
"body": "eyJtZXNzYWdlIjoiSGVsbG8sIEpvaG4hIiwidXNlcl9kYXRhIjoibXlkYXRhIiwic2VjcmV0X3VzZXJfZGF0YSI6Im15c2VjcmV0In0=",
"headers": {
"Content-Type": [
"application/json"
],
"Date": [
"Fri, 18 Sep 2026 07:37:43 GMT"
],
"Host": [
"host"
],
"X-Powered-By": [
"PHP/8.3.6"
]
},
"statusCode": 200,
"isBase64Encoded": true
}
The body in the output is base64 encoded. After decoding, you should see the following content:
{"message":"Hello, John!","user_data":"mydata","secret_user_data":"mysecret"}