函数计算PHP Runtime - exception 处理

本文涉及的产品
简介: 本文中,详细解析了函数计算 php runtime 中对于异常的处理, 在php runtime 中,严格规范代码,我们期望加强检查以便减少用户编写diamante犯错的可能,但是针对一些第三方库的引入使用可能因为warning或者notice而无法使用时,函数计算允许用户通过自定义的set_error_handler来覆盖runtime中默认处理。

主目录:php runtime FAQ

在本文中,我们来细化讲讲函数计算中 php runtime 中的异常处理问题,在官方文档中 php runtime 错误处理 没有讲解函数计算php runtime 环境中对于具体的错误类型是怎么处理的?比如级别很低的notice或者warning, 先来看几个例子:

example

Warning

<?php
function handler($event, $context) {
  $a = 1/0;
  return "ok";
}

执行结果:

{
   "errorMessage": "Division by zero",
   "errorType": "ErrorException",
   "stackTrace": {
      "file": "/code/index.php",
      "line": 3,
      "traceString": ""
   }
} 

NOTICE

<?php
function handler($event, $context) {
  $a = ["a" => 1, "b" => 2];
  $b = $a["c"];
  return "ok";
}

执行结果:

 {
   "errorMessage": "Undefined index: c",
   "errorType": "ErrorException",
   "stackTrace": {
      "file": "/code/index.php",
      "line": 11,
      "traceString": ""
   }
} 

从上面两个例子我们可以看出,函数计算的 php runtime 对代码检查十分严格,不管什么级别的ERROR_TYPE, 都是按照异常来处理,但是有些使用有些php库的时候,可能会有一些warning或者notice,这个时候会导致在函数计算的环境中不能使用这种php 库,比如aliyun-openapi-php-sdk

比如下面的代码:

<?php

require_once __DIR__ . '/aliyun-openapi-php-sdk/aliyun-php-sdk-core/Config.php';
use imm\Request\V20170906 as Imm;

define('PREVIEWURL', 'https://preview.imm.aliyun.com/index.html');

function handler($event, $context) {
    $accessKeyId     = $context["credentials"]["accessKeyId"];
    $accessKeySecret = $context["credentials"]["accessKeySecret"];
    $securityToken   = $context["credentials"]["securityToken"];
    $region          = $context['region'];

    $iClientProfile = DefaultProfile::getProfile(
        $region,
        $accessKeyId,
        $accessKeySecret,
        $securityToken
    );

    $client         = new DefaultAcsClient($iClientProfile);
    $PREVIEWTGTPATH = 'fc-demo-preview-output-php';
    $immProject     = "imm-demo";
    $srcUri         = "oss://fc-imm-demo/test-data/office/test.pptx";

    $bucket   = "fc-imm-demo";
    $fileName = "test.pptx";
    $tgtUri   = sprintf("oss://%s/%s/%s", $bucket, $PREVIEWTGTPATH, $fileName);

    $request = new Imm\CreateOfficeConversionTaskRequest();
    $request->setProject($immProject);
    $request->setSrcUri($srcUri);
    $request->setTgtType("vector");
    $request->setTgtUri($tgtUri);
    $response = $client->getAcsResponse($request);
    print_r($response);
}

执行就会收到这个错误, 上面 example 中的 NOTICE 转变为exception:

 {
   "errorMessage": "Undefined index: cn-hangzhou#imm",
   "errorType": "ErrorException",
   "stackTrace": {
      "file": "/code/aliyun-openapi-php-sdk/aliyun-php-sdk-core/Regions/LocationService.php",
      "line": 58,
      "traceString": ""
   }
} 

php runtime 中自定义error_handler

当遇见上面所述对的问题时,我们如何规避这种问题呢?答案是使用set_error_handler 来定义自己的处理方法,从而屏蔽runtime中严格处理, 对于 Warning 和 Notice 这种级别等错误, 详情可以参考:http://www.php.net/manual/zh/function.set-error-handler.php

对于上面这种问题,我们修改代码如下:

<?php

require_once __DIR__ . '/aliyun-openapi-php-sdk/aliyun-php-sdk-core/Config.php';
use imm\Request\V20170906 as Imm;

define('PREVIEWURL', 'https://preview.imm.aliyun.com/index.html');

function myErrorHandler($errno, $errstr, $errfile, $errline) {
    if (!(error_reporting() & $errno)) {
        return false;
    }

    switch ($errno) {
    case E_USER_ERROR:
        $errInfo = array(
            "errorMessage" => $errstr,
            "errorType"    => \ServerlessFC\friendly_error_type($errno),
            "stackTrace"   => array(
                "file" => $errfile,
                "line" => $errline,
            ),
        );
        throw new \ErrorException($errstr, 0, $errno, $errfile, $errline);
        break;

    default: // E_USER_WARNING | E_USER_NOTICE
        break;
    }

    /* Don't execute PHP internal error handler */
    return true;
}

function handler($event, $context) {
    // set to the user defined error handler
    set_error_handler("myErrorHandler");
    
    $accessKeyId     = $context["credentials"]["accessKeyId"];
    $accessKeySecret = $context["credentials"]["accessKeySecret"];
    $securityToken   = $context["credentials"]["securityToken"];
    $region          = $context['region'];

    $iClientProfile = DefaultProfile::getProfile(
        $region,
        $accessKeyId,
        $accessKeySecret,
        $securityToken
    );

    $client         = new DefaultAcsClient($iClientProfile);
    $PREVIEWTGTPATH = 'fc-demo-preview-output-php';
    $immProject     = "imm-demo";
    $srcUri         = "oss://fc-imm-demo/test-data/office/test.pptx";

    $bucket   = "fc-imm-demo";
    $fileName = "test.pptx";
    $tgtUri   = sprintf("oss://%s/%s/%s", $bucket, $PREVIEWTGTPATH, $fileName);

    $request = new Imm\CreateOfficeConversionTaskRequest();
    $request->setProject($immProject);
    $request->setSrcUri($srcUri);
    $request->setTgtType("vector");
    $request->setTgtUri($tgtUri);
    $response = $client->getAcsResponse($request);
    print_r($response);
}

总结

本文中,详细解析了函数计算 php runtime 中对于异常的处理, 在php runtime 中,严格规范代码,我们期望加强检查以便减少用户编写代码犯错的可能,但是针对一些第三方库的引入使用可能因为warning或者notice而无法使用时,函数计算允许用户通过自定义的set_error_handler来覆盖runtime中默认处理。

相关实践学习
基于函数计算一键部署掌上游戏机
本场景介绍如何使用阿里云计算服务命令快速搭建一个掌上游戏机。
建立 Serverless 思维
本课程包括: Serverless 应用引擎的概念, 为开发者带来的实际价值, 以及让您了解常见的 Serverless 架构模式
目录
相关文章
|
6月前
|
Serverless
函数计算,php7.2内置运行时是单并发吗?为什么设置不了并发数?
函数计算,php7.2内置运行时是单并发吗?为什么设置不了并发数?
61 2
|
3月前
|
缓存 弹性计算 NoSQL
您在使用Serverless应用引擎(SAE)部署PHP应用时遇到了性能问题
【1月更文挑战第12天】【1月更文挑战第57篇】您在使用Serverless应用引擎(SAE)部署PHP应用时遇到了性能问题
352 1
|
7月前
|
弹性计算 监控 负载均衡
10分钟Serverless部署PHP商城
.本实验带您体验如何使用 Serverless 应用引擎 SAE 快速部署一个PHP商城,并体验 SAE 带来的弹性伸缩、应用监控能等强大能力。
212 0
|
Serverless PHP
体验有奖丨1 分钟 Serverless 部署 PHP 商城,赢取天猫超市卡
体验有奖丨1 分钟 Serverless 部署 PHP 商城,赢取天猫超市卡
体验有奖丨1 分钟 Serverless 部署 PHP 商城,赢取天猫超市卡
|
弹性计算 监控 Serverless
体验有奖丨1 分钟 Serverless 部署 PHP 商城,赢取天猫超市卡
体验有奖丨1 分钟 Serverless 部署 PHP 商城,赢取天猫超市卡
体验有奖丨1 分钟 Serverless 部署 PHP 商城,赢取天猫超市卡
|
运维 Kubernetes Cloud Native
serverless 学习 | QCon2022-深圳: Serverless 高密度部署与 Web-interoperable Runtime 在字节跳动的实践
serverless 学习 | QCon2022-深圳: Serverless 高密度部署与 Web-interoperable Runtime 在字节跳动的实践
349 0
serverless 学习 | QCon2022-深圳: Serverless 高密度部署与 Web-interoperable Runtime 在字节跳动的实践
|
JSON 监控 Serverless
如何将gitee仓库的php源码快速托管到阿里云函数计算
如何将gitee仓库的php源码快速托管到阿里云函数计算
426 0
如何将gitee仓库的php源码快速托管到阿里云函数计算
|
运维 前端开发 Serverless
PHP 遇见 Serverless,帮你解决这些痛点!
从下文的讨论和陈述中,我们不难发现,PHP 遇见 Serverless 是一件令人兴奋的事情,让 phper 有了更大的想象空间。Serverless 的理念和 PHP 这个语言出现的理念也是一致的: 即让开发者最大精力集中在自己的业务价值。PHP 语言一直是 web 领域最好的生产力代表,而 Serverless 将会让 PHP 如虎添翼。
PHP 遇见 Serverless,帮你解决这些痛点!
|
Java Serverless
FC Java runtime 找不到函数入口问题
在函数计算中使用Java编程时,需要定义一个函数作为入口函数。由于Java有包的概念,因此执行方法和其他语言有所不同,需要带有包信息。在入口函数需要配置包信息
593 0
FC Java runtime 找不到函数入口问题
|
Shell Serverless PHP
函数计算 php 运行环境添加 pdo_sqlite 扩展
编译pdo_sqlite并添加到函数计算php运行环境
676 0
函数计算 php 运行环境添加 pdo_sqlite 扩展

相关产品

  • 函数计算