内容字号:默认大号超大号

段落设置:段首缩进取消段首缩进

字体设置:切换到微软雅黑切换到宋体

函数计算PHP Runtime exception处理

2018-10-04 18:18 出处:清屏网 人气: 评论(0

在本文中,我们来细化讲讲函数计算中 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;
}

// set to the user defined error handler
set_error_handler("myErrorHandler");

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);
}

总结

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

分享给小伙伴们:
本文标签: PHPRuntimeexception

相关文章

发表评论愿您的每句评论,都能给大家的生活添色彩,带来共鸣,带来思索,带来快乐。

CopyRight © 2015-2016 QingPingShan.com , All Rights Reserved.

清屏网 版权所有 豫ICP备15026204号