Function Compute supports the PHP 7.2 runtime environment. This topic describes log printing, error handling, PHP extensions, custom packages, and external commands in the PHP runtime environment.

Log printing

Function Compute provides a built-in logger module. You can use $GLOBALS['fcLogger'] to collect and store printed logs in the Logstore that you specify when you create a service.

  • Log level

    You can call the setLevel method to specify the level of logs that you want to print. The following table describes the log levels by severity from high to low.

    Log level Level Operation Description
    EMERGENCY 600 $logger->emergency Emergency logs
    ALERT 550 $logger->alert Alert logs
    CRITICAL 500 $logger->critical Critical warnings
    ERROR 400 $logger->error Error messages
    WARNING 300 $logger->warning Warnings
    NOTICE 250 $logger->notice Notifications and general logs
    INFO (default severity) 200 $logger->info Output details
    DEBUG 100 $logger->debug Debugging logs

    For more information about function logs, see Grant an event source permissions to access Function Compute.

  • Example 1
    <?php
    function handler($event, $context) {
        $logger = $GLOBALS['fcLogger'];
        $logger->info("hello world");
        return 'hello world';
    };           

    After you run the preceding code, the following log is printed:

    message:2017-07-05T05:13:35.920Z a72df088-f738-cee3-e0fe-323ad89118e5 [INFO] hello world            
  • Example 2
    <?php
    use Monolog\Logger;
    function handler($evt, $ctx) {
        $logger = $GLOBALS['fcLogger'];
        $logger->setLevel(400);
        $logger->error("console error 1");
        $logger->info("console info 1");
        $logger->warning("console warn 1");
        $logger->debug("console debug 1");
    
        $logger->setLevel(Logger::WARNING);
        $logger->error("console error 2");
        $logger->info("console info 2");
        $logger->warn("console warn 2");
        $logger->debug("console debug 2");
    
        $logger->setLevel(200);
    }            

    After you run the preceding code, the following logs are printed:

    2018-08-22T09:01:26Z c19b2706-9c4d-270b-52c8-5248ed5e2315 [ERROR]: console error 1
    2018-08-22T09:01:26Z c19b2706-9c4d-270b-52c8-5248ed5e2315 [ERROR]: console error 2
    2018-08-22T09:01:26Z c19b2706-9c4d-270b-52c8-5248ed5e2315 [WARNING]: console warn 2            

Troubleshooting

Function Compute captures exceptions that occur when you invoke a PHP function and returns information about the exceptions. In the following sample code, the information about the oops exception is returned.

<?php
function handler($event, $context) {
  throw new Exception("oops");
}           

The system returns the following response when you invoke the function:

{
    "errorMessage":"oops",
    "errorType":"Exception",
    "stackTrace":{
        "file":"/code/index.php",
        "line":3,
        "traceString":"#0 /var/fc/runtime/php7/src/invoke.php(67): handler('{\n "product"...', Array)
#1 "
    }
}           

If an error occurs, the HTTP header in the response contains X-Fc-Error-Type: UnhandledInvocationError. For more information about error types in Function Compute, see Troubleshooting.

Built-in PHP extensions

This section describes built-in extensions for the PHP runtime environment and provides examples on how to use the extensions.

Built-in extensions

Note If you want to view and print the information about installed PHP extensions, include print_r(get_loaded_extensions()); in the code of the specified function.
bcmath bz2 calendar Core
ctype curl date dom
exif fileinfo filter ftp
gd gettext gmp hash
iconv imagick json libxml
mbstring memcached mysqli mysqlnd
openssl pcntl pcre PDO
pdo_mysql Phar posix protobuf
readline redis Reflection session
shmop SimpleXML soap sockets
SPL standard sysvmsg sysvsem
sysvshm tokenizer xdebug xml
xmlreader xmlrpc xmlwriter Zend OPcache
zip zlib Xdebug Zend OPcache

Example

In the following sample code, imagick is used to process an image:

<?php
function imageProc($event, $context) {
    $image = new Imagick(__DIR__ . '/lena.jpg');
    $image->thumbnailImage(100, 0);
    $image->writeImages(__DIR__ . "/thumb.jpg", true);
    return strval($image->getImageWidth()) . "," . strval($image->getImageHeight());
}           

Install non-built-in PHP extensions

If you want to use non-built-in extensions for the PHP runtime environment, perform the following steps to install them:

  1. Run the following command in a project directory, go to the image of the PHP runtime environment, and then mount the current directory to the /code directory of a container:
    docker run -v $(pwd):/code -it --entrypoint=""  registry.cn-beijing.aliyuncs.com/aliyunfc/runtime-php7.2:latest  bash
    Note If your computer runs Windows, you can change $(pwd) to a specific absolute directory.
  2. Install an extension of MongoDB and copy the mongodb.so file to the /code directory.
    1. Run the following command to install the extension of MongoDB in the container:
      pecl install mongodb
    2. Run the following command to find the ZIP extension:
      find /usr -name "mongodb.so"
    3. Run the following command to copy the extension file to the /code directory:
      cp /usr/local/lib/php/extensions/no-debug-non-zts-20170718/mongodb.so /code
    4. Run the following command to exit the container:
      exit
    5. Run the following command to check whether the zip.so file exists. If the file exists, the .so file is stored on your computer.
      ls
      Expected output:
      mongodb.so
  3. Log on to the Function Compute console.
  4. In the left-side navigation pane, click Services and Functions.
  5. In the top navigation bar, select the region where your Kubernetes cluster is deployed.
  6. On the Services page, click the target service.
  7. On the Functions page of the specified service, click the specified function. On the Code tab, create the extension folder in the directory in which the handler function files are stored.
    Note The extension folder that you create must be at the same level as the bootstrap file.
  8. Add the mongodb.so file to the extension folder, and create the mongodb.ini file in the extension folder.
  9. Edit the mongodb.ini file.
    Add the following content to the mongodb.ini file and save the file:
    extension=/code/extension/mongodb.so
If you want to install one of the following custom extensions, download them based on your business requirements:

Use built-in PHP packages

Function Compute provides the following built-in packages for the PHP runtime environment:

Package Version Description
oss v2.3.0 Object Storage Service (OSS) SDK for PHP
tablestore v4.1.0 TableStore SDK for PHP
mns v1.3.5.5 Message Service (MNS) SDK for PHP
fc v1.1.0 Function Compute SDK for PHP

Example

The following sample code shows how to use OSS SDK for PHP to upload a .txt file:

<?php
use OSS\OssClient;
function handler($event, $context) {
     $accessKeyId = $context["credentials"]["accessKeyId"];
     $accessKeySecret = $context["credentials"]["accessKeySecret"];
     $securityToken = $context["credentials"]["securityToken"];
     $endpoint = "oss-cn-shenzhen.aliyuncs.com";
     $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, false, $securityToken);
     $bucket = "my-bucket";
     $object = "php.txt";
     $content = "Hello fc!";
     try {
        $ossClient->putObject($bucket, $object, $content);
     } catch (OssException $e) {
        print($e->getMessage());
     }
    return 'success';
}           

Use custom PHP packages

Install custom packages

Function Compute also allows you to install custom PHP packages. This section describes the methods that you can use to install custom packages.

  • Method 1: Use Composer to install custom packages (Recommended)

    If the package that you want to use is from Packagist, the PHP Package Repository, you can use Composer to install the package. The following example shows how to install Humble HTTP request library package requests:

    1. Create a folder to store code and dependent modules.
      mkdir /tmp/code       
    2. Create a code file, such as /tmp/code/index.php, and use requests in the code.
      <?php
      require_once __DIR__ . "/vendor/autoload.php";
      function handler($event, $context){
         $headers = array('Accept' => 'application/json');
         $options = array('auth' => array('user', 'pass'));
         $request = Requests::get('https://www.example.com', $headers, $options);
         var_dump($request->status_code);
         // int(200)
         var_dump($request->headers['content-type']);
         // string(31) "application/json; charset=utf-8"
         var_dump($request->body);
         // string(26891) "[...]"
      }            
    3. Install a custom package in the /tmp/code directory.
      1. Create a composer.json file and add the following content to the file:
        {
            "require": {
                "rmccue/requests": ">=1.0"
            }
        }           
      2. Run the following command to go to the code directory:
        cd /tmp/code
      3. Run the following command to install dependencies:
        composer install --no-dev            
  • Method 2: Download a custom package
    If the package, such as Aliyun-openapi-php-sdk or Log Service SDK for PHP, that you want to use is unavailable in Packagist, you can download the package and reference the package in the code. The following example shows how to add a custom package of Log Service SDK for PHP:
    1. Create a folder to store code and dependent modules.
      mkdir /tmp/code            
    2. Create a code file, such as /tmp/code/index.php, and use requests in the code.
      <?php
      /* Use the autoloader class to load all required PHP modules. Make sure that a valid path of the file that contains the autoloader class is specified.  */
      require_once realpath(dirname(__FILE__) . '/aliyun-log-php-sdk/Log_Autoload.php');
      function handler($event, $context){
         $endpoint = 'cn-hangzhou.sls.aliyuncs.com'; // Specify an endpoint that matches the region of the Log Service project that is created in the preceding process. 
         $accessKeyId = 'your_access_key_id';        // Specify the AccessKey ID of your Alibaba Cloud account. 
         $accessKey = 'your_access_key';             // Specify the AccessKey secret of your Alibaba Cloud account. 
         $project = 'your_project';                  // Specify the name of the Log Service project. 
         $logstore = 'your_logstore';                // Specify the name of the Log Service Logstore. 
         $client = new Aliyun_Log_Client($endpoint, $accessKeyId, $accessKey);
         # Query the names of all Logstores in the current Log Service project. 
         $req1 = new Aliyun_Log_Models_ListLogstoresRequest($project);
         $res1 = $client->listLogstores($req1);
         var_dump($res1);
      }            
    3. Download dependencies to the /tmp/code directory.
      cd /tmp/code
      git clone https://github.com/aliyun/aliyun-log-php-sdk.git           

Package files and upload them to Function Compute.

You must package the specified files instead of the code directory. After you package the files, make sure that the files of the handler function are stored in the root directory of the package.

  • In Windows, you can select all files in the code directory of the function, right-click these files, and then compress the files into a code package in the ZIP format.
  • In Linux, when you call the zip command, you must specify all files in the specified code directory as source files to generate a deployment code package. For example, you can run the zip code.zip /home/code/* command.
    Notice For macOS and Linux operating systems, make sure that the code file is readable and executable before compression.

After the files are packaged, go to the Function Compute console. On the Code tab, select Import from OSS or Upload Zip File to upload the code package.

Run external commands

If you want to run external tools, such as shell scripts and executable files compiled in C++ or Go in your PHP functions, you can package and upload the tools and code together, and then run external commands to use these tools. You can use the following PHP methods to run external commands: exec, system, and shell-exec.

Note The shell scripts and executable files that are compiled in C++ and Go must be compatible with the runtime environment of Function Compute. The PHP runtime environment in Function Compute is developed based on Linux 4.4.24-2.al7.x86_64 and Docker pull php:7.2.

The following sample code shows how to use the exec method to call a shell script.

<?php
function handler($evt, $ctx){
    $script = $_ENV['FC_FUNC_CODE_PATH'] . '/script.sh';
    $a = exec("bash " . $script, $out, $status);
    print_r($a);
    var_dump($out);
    print_r($status);
}