• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • 返回值

    值通过使用可选的返回语句返回。可以返回包括数组和对象的任意类型。返回语句会立即中止函数的运行,并且将控制权交回调用该函数的代码行。更多信息见return。

    Note:

    如果省略了return,则返回值为NULL

    return 的使用

    Example #1 return的使用

    <?php
    function square($num)
    {
        return $num * $num;
    }
    echo square(4);   // outputs '16'.
    ?>
    

    函数不能返回多个值,但可以通过返回一个数组来得到类似的效果。

    Example #2 返回一个数组以得到多个返回值

    <?php
    function small_numbers()
    {
        return array (0, 1, 2);
    }
    list ($zero, $one, $two) = small_numbers();
    ?>
    

    从函数返回一个引用,必须在函数声明和指派返回值给一个变量时都使用引用运算符&:

    Example #3 从函数返回一个引用

    <?php
    function &returns_reference()
    {
        return $someref;
    }
    $newref =& returns_reference();
    ?>
    

    有关引用的更多信息,请查看引用的解释。

    返回值类型声明

    PHP 7 增加了对返回值类型声明的支持。就如类型声明一样,返回值类型声明将指定该函数返回值的类型。同样,返回值类型声明也与有效类型中可用的参数类型声明一致。

    严格类型也会影响返回值类型声明。在默认的弱模式中,如果返回值与返回值的类型不一致,则会被强制转换为返回值声明的类型。在强模式中,返回值的类型必须正确,否则将会抛出一个TypeError异常.

    Note:

    当覆盖一个父类方法时,子类方法的返回值类型声明必须与父类一致。如果父类方法没有定义返回类型,那么子类方法可以定义任意的返回值类型声明。

    范例

    Example #4 基础返回值类型声明

    <?php
    function sum($a, $b): float {
        return $a + $b;
    }
    // Note that a float will be returned.
    var_dump(sum(1, 2));
    ?>
    

    以上例程会输出:

    float(3)
    

    Example #5 严格模式下执行

    <?php
    declare(strict_types=1);
    function sum($a, $b): int {
        return $a + $b;
    }
    var_dump(sum(1, 2));
    var_dump(sum(1, 2.5));
    ?>
    

    以上例程会输出:

    int(3)
    Fatal error: Uncaught TypeError: Return value of sum() must be of the type integer, float returned in - on line 5 in -:5
    Stack trace:
    #0 -(9): sum(1, 2.5)
    #1 {main}
      thrown in - on line 5
    

    Example #6 返回一个对象

    <?php
    class C {}
    function getC(): C {
        return new C;
    }
    var_dump(getC());
    ?>
    

    以上例程会输出:

    object(C)#1 (0) {
    }
    
    PHP 7.1 allows for void and null return types by preceding the type declaration with a ? -- (e.g. function canReturnNullorString(): ?string) 
    However resource is not allowed as a return type:
    <?php
    function fileOpen(string $fileName, string $mode): resource
    {
      $handle = fopen($fileName, $mode);
      if ($handle !== false)
      {
        return $handle;
      }
    }
    $resourceHandle = fileOpen("myfile.txt", "r");
    ?>
    Errors with:
    Fatal error: Uncaught TypeError: Return value of fileOpen() must be an instance of resource, resource returned.
    Developers with a C background may expect pass by reference semantics for arrays. It may be surprising that pass by value is used for arrays just like scalars. Objects are implicitly passed by reference.
    <?php
    # (1) Objects are always passed by reference and returned by reference
    class Obj {
      public $x;
    }
    function obj_inc_x($obj) {
      $obj->x++;
      return $obj;
    }
    $obj = new Obj();
    $obj->x = 1;
    $obj2 = obj_inc_x($obj);
    obj_inc_x($obj2);
    print $obj->x . ', ' . $obj2->x . "\n";
    # (2) Scalars are not passed by reference or returned as such
    function scalar_inc_x($x) {
      $x++;
      return $x;
    }
    $x = 1;
    $x2 = scalar_inc_x($x);
    scalar_inc_x($x2);
    print $x . ', ' . $x2 . "\n";
    # (3) You have to force pass by reference and return by reference on scalars
    function &scalar_ref_inc_x(&$x) {
      $x++;
      return $x;
    }
    $x = 1;
    $x2 =& scalar_ref_inc_x($x);  # Need reference here as well as the function sig
    scalar_ref_inc_x($x2);
    print $x . ', ' . $x2 . "\n";
    # (4) Arrays use pass by value sematics just like scalars
    function array_inc_x($array) {
      $array{'x'}++;
      return $array;
    }
    $array = array();
    $array['x'] = 1;
    $array2 = array_inc_x($array);
    array_inc_x($array2);
    print $array['x'] . ', ' . $array2['x'] . "\n";
    # (5) You have to force pass by reference and return by reference on arrays
    function &array_ref_inc_x(&$array) {
      $array{'x'}++;
      return $array;
    }
    $array = array();
    $array['x'] = 1;
    $array2 =& array_ref_inc_x($array); # Need reference here as well as the function sig
    array_ref_inc_x($array2);
    print $array['x'] . ', ' . $array2['x'] . "\n";
    Be careful about using "do this thing or die()" logic in your return lines. It doesn't work as you'd expect:
    <?php
    function myfunc1() {
      return('thingy' or die('otherthingy'));
    }
    function myfunc2() {
      return 'thingy' or die('otherthingy');
    }
    function myfunc3() {
      return('thingy') or die('otherthingy');
    }
    function myfunc4() {
      return 'thingy' or 'otherthingy';
    }
    function myfunc5() {
      $x = 'thingy' or 'otherthingy'; return $x;
    }
    echo myfunc1(). "\n". myfunc2(). "\n". myfunc3(). "\n". myfunc4(). "\n". myfunc5(). "\n";
    ?>
    Only myfunc5() returns 'thingy' - the rest return 1.
    With 7.1, these are possible yet;
    <?php
    function ret_void(): void {
      // do something but no return any value
      // if needs to break fn exec for any reason simply write return;
      if (...) {
        return; // break
        // return null; // even this NO!
      }
      $db->doSomething();
      // no need return call anymore 
    }
    function ret_nullable() ?int {
      if (...) {
        return 123;
      } else {
        return null; // MUST!
      }
    }
    ?>
    
    Be careful when introducing return types to your code.
    Only one return type can be specified (but prefacing with ? allows null).
    Return values of a type different to that specified are silently converted with sometimes perplexing results. These can be tedious to find and will need rewriting, along with calling code.
    Declare strict types using "declare(strict_types=1);" and an error will be generated, saving much head-scratching.
    You may specify child return type if there is no parent:
    <?php
    class A {
      public function f ($a)
      {
        return 1;
      }
    }
    class B extends A {
      public function f ($a): int // + return type, OK
      {
        return 1;
      }
    }
    class C extends A {
      public function f (int $a) // + argument type, WARNING
      {
        return 1;
      }
    }
    ?>
    
    Functions which return references, may return a NULL value. This is inconsistent with the fact that function parameters passed by reference can't be passed as NULL (or in fact anything which isnt a variable).
    i.e.
    <?php
    function &testRet()
    {
      return NULL;
    }
    if (testRet() === NULL)
    {
      echo "NULL";
    }
    ?>
    parses fine and echoes NULL
    PHP 7 return types if specified can not return a null.
    For example:
    <?php
    declare(strict_types=1);
    function add2ints(int $x, int $y): int
    {
      $z = $x + $y;
      if ($z===0)
      {
        return null;
      }
      return $z;
    }
    $a = add2ints(3, 4);
    echo is_null($a) ? 'Null' : $a;
    $b = add2ints(-2, 2);
    echo is_null($b) ? 'Null' : $b;
    exit();
    Output:
    7
    Process finished with exit code 139
    Declaring a collection of objects as return type is not implemented and forbidden:
    <?php
    class Child{}
    function getChilds(): Child[]
    {
      return [(new Child()), (new Child())];
    }
    var_dump(getChilds());
    // Returns: Parse error: syntax error, unexpected '[', expecting '{'
    ?>
    We have to use:
    <?php
    class Child{}
    function getChilds(): array
    {
      return [(new Child()), (new Child())];
    }
    var_dump(getChilds());
    // Returns: 
    /*
    array (size=2)
     0 =>
      object(Child)[168]
     1 =>
      object(Child)[398]
    */
    ?>
    Idem for function parameter:
    <?php
    function setChilds(Child[] $childs){}
    // Not allowed
    function setChilds(array $childs){}
    // Allowed
    ?>
    
    Note: the function does not have "alternative syntax" as if/endif, while/endwhile, and colon (:) here is used to define returning type and not to mark where the block statement begins.
    Just a quick clarification on whether variables are passed by reference or not. Variables are always passed using a pointer, and if the variable is modified, it is copied and re-assigned. For example:
    <?php
    function byPointer($x) {
      return $x / 3; // Does not modify or create a copy of $x
    }
    function copied($x) {
      $x++; // At this point, creates a copy of $x to be used in local scope
      return $x;
    }
    class Obj {
      public function performAction() {}
      public $y;
    }
    function objPointer(Obj $x) {
      $x->performAction(); //works on $x
      $x->y = '150'; //works on $x
      $x = new Obj(); // Does not modify $x outside of function
      $x->y = '250';
    }
    function objReference(Obj &$x) {
      $x->performAction(); //works on $x
      $x->y = '150'; //works on $x
      $x = new Obj(); // Modifies original $x outside of function
      $x->y = '250';
    }
    $x = new Obj();
    $x->y = '10';
    objPointer($x);
    echo "Post Pointer: {$x->y}\n";
    $x->y = '10';
    objReference($x);
    echo "Post Reference: {$x->y}\n";
    ?>
    This will output:
    Post Pointer: 150
    Post Reference: 250
    So make sure when writing functions that if you want to pass by reference you actually mean by reference, and not using standard PHP pointers
    In reference to the poster above, an additional (better?) way to return multiple values from a function is to use list(). For example:
    function fn($a, $b)
    {
      # complex stuff
      return array(
       $a * $b,
       $a + $b,
      );
    }
    list($product, $sum) = fn(3, 4);
    echo $product; # prints 12
    echo $sum; # prints 7
    If a function/method parameter has a type declaration , then php compiler will check it the moment of invocation regardless if strict_types is set to 1 or 0 or not set at all.
    However, php will check parameters types on build in php functions when strict_types is set to 1;
    I like this method of concatinating methods by returning $this. It makes my code more readable. If the returned value is not an object it will fail and you find mistakes easier.
    <?php
    class Dummy {
      private $result;
      function __construct()
      {
        $this->result =
          $this
            ->setStuff('abc')
            ->generateResult()
          ;
      }
      
      function setStuff($value)
      {
        // do something
        return $this;
      }
      function generateResult()
      {
        return ['the result'];
      }
      function getResult()
      {
        return $this->result;
      }
    }
    ?>
    

    上篇:函数的参数

    下篇:可变函数