PHP入门笔记--基础语法二

一、函数

  1. 自定义函数

    • 任何有效的 PHP 代码都有可能出现在函数内部,甚至包括其它函数和类定义。

      <?php
      function foo()
      {
        function bar()
        {
          echo "I don't exist until foo() is called.\n";
        }
      }
      
      /* 现在还不能调用bar()函数,因为它还不存在 */
      
      foo();
      
      /* 现在可以调用bar()函数了,因为foo()函数
         的执行使得bar()函数变为已定义的函数 */
      
      bar();
      
      ?>
      
    • PHP 中的所有函数和类都具有全局作用域,可以定义在一个函数之内而在之外调用,反之亦然。

    • PHP 不支持函数重载,也不可能取消定义或者重定义已声明的函数。

  2. 函数的参数

    • 参数是从左向右求值

    • 默认参数, 注意当使用默认参数时,任何默认参数必须放在任何非默认参数的右侧

      <?php
      function makecoffee($types = array("cappuccino"), $coffeeMaker = NULL)
      {
          $device = is_null($coffeeMaker) ? "hands" : $coffeeMaker;
          return "Making a cup of ".join(", ", $types)." with $device.\n";
      }
      echo makecoffee();
      echo makecoffee(array("cappuccino", "lavazza"), "teapot");
      
      function makeyogurt($flavour, $type = "acidophilus")
      {
          return "Making a bowl of $type $flavour.\n";
      }
      echo makeyogurt("raspberry");   // works as expected
      ?>
      
  3. 返回值

    • 返回一个数组以得到多个返回值。

      <?php
      function small_numbers()
      {
          return array (0, 1, 2);
      }
      list ($zero, $one, $two) = small_numbers();
      ?>
      
    • 从函数返回一个引用。必须在函数声明和指派返回值给一个变量时都使用引用运算符 &。

      <?php
      function &returns_reference()
      {
          return $someref;
      }
      
      $newref =& returns_reference();
      ?>
      
  4. 可变函数

    PHP 支持可变函数的概念。这意味着如果一个变量名后有圆括号,PHP 将寻找与变量的值同名的函数,并且尝试执行它。

    <?php
    function foo() {
        echo "In foo()<br />\n";
    }
    
    function bar($arg = '') {
        echo "In bar(); argument was '$arg'.<br />\n";
    }
    
    // 使用 echo 的包装函数
    function echoit($string)
    {
        echo $string;
    }
    
    $func = 'foo';
    $func();        // This calls foo()
    
    $func = 'bar';
    $func('test');  // This calls bar()
    
    $func = 'echoit';
    $func('test');  // This calls echoit()
    ?>
    

    当调用静态方法时,函数调用要比静态属性优先。

二、类与对象

  1. 基本概念

    • $this

      当一个方法在类定义内部被调用时,有一个可用的伪变量$this。$this 是一个到主叫对象的引用(通常是该方法所从属的对象,但如果是从第二个对象静态调用时也可能是另一个对象)。

      <?php
      class A
      {
          function foo()
          {
              if (isset($this)) {
                  echo '$this is defined (';
                  echo get_class($this);
                  echo ")\n";
              } else {
                  echo "\$this is not defined.\n";
              }
          }
      }
      
      class B
      {
          function bar()
          {
              // Note: the next line will issue a warning if E_STRICT is enabled.
              A::foo();
          }
      }
      
      $a = new A();
      $a->foo();  //$this is defined (A)
      
      // Note: the next line will issue a warning if E_STRICT is enabled.
      A::foo();  //$this is not defined.
      $b = new B();
      $b->bar();  //$this is defined (B)
      
      // Note: the next line will issue a warning if E_STRICT is enabled.
      B::bar();  //$this is not defined.
      ?>
      
    • new

      当创建新对象时该对象总是被赋值,除非该对象定义了构造函数并且在出错时抛出了一个异常。类应在被实例化之前定义。

      在类定义内部,可以用 new self 和 new parent 创建新对象。

    • extends

      一个类可以在声明中用 extends 关键字继承另一个类的方法和属性。PHP不支持多重继承,一个类只能继承一个基类。

      被继承的方法和属性可以通过用同样的名字重新声明被覆盖。但是如果父类定义方法时使用了final,则该方法不可被覆盖。可以通过parent:: 来访问被覆盖的方法或属性。

      当覆盖方法时,参数必须保持一致否则 PHP 将发出 E_STRICT 级别的错误信息。但构造函数例外,构造函数可在被覆盖时使用不同的参数。

      <?php
      class ExtendClass extends SimpleClass
      {
          // Redefine the parent method
          function displayVar()
          {
              echo "Extending class\n";
              parent::displayVar();
          }
      }
      
      $extended = new ExtendClass();
      $extended->displayVar();
      ?>
      
    • ::class

      关键词 class 也可用于类名的解析。使用 ClassName::class 你可以获取一个字符串,包含了类 ClassName 的完全限定名称。这对使用了 命名空间 的类尤其有用。

      <?php
      namespace NS {
          class ClassName {
          }
          
          echo ClassName::class;  //NS\ClassName
      }
      ?>
      
  2. 属性

    访问控制:publicprotected 和 private

    在类的成员方法里面,可以用 ->(对象运算符):$this->property(其中 property 是该属性名)这种方式来访问非静态属性。静态属性则是用 ::(双冒号):self::$property 来访问。

  3. 类常量

    在定义和使用常量的时候不需要使用 $ 符号。

    <?php
    class MyClass
    {
        const constant = 'constant value';
    
        function showConstant() {
            echo  self::constant . "\n";
        }
    }
    
    echo MyClass::constant . "\n";
    
    $classname = "MyClass";
    echo $classname::constant . "\n"; // 自 5.3.0 起
    
    $class = new MyClass();
    $class->showConstant();
    
    echo $class::constant."\n"; // 自 PHP 5.3.0 起
    ?>
    
  4. 类的自动加载

    很多开发者为每个类新建一个 PHP 文件。 这会带来一个烦恼:每个脚本的开头,都需要包含(include)一个长长的列表(每个类都有个文件)。

    spl_autoload_register() 函数可以注册任意数量的自动加载器,当使用尚未被定义的类(class)和接口(interface)时自动去加载。通过注册自动加载器,脚本引擎在 PHP 出错失败前有了最后一个机会加载所需的类。

    本例尝试分别从 MyClass1.php 和 MyClass2.php 文件中加载 MyClass1 和 MyClass2 类。

   <?php
   spl_autoload_register(function ($class_name) {
       require_once $class_name . '.php';
   });
   
   $obj  = new MyClass1();
   $obj2 = new MyClass2();
   ?>
  1. 构造函数和析构函数

    void __construct ([ mixed $args [, $... ]] )

    如果子类中定义了构造函数则不会隐式调用其父类的构造函数。要执行父类的构造函数,需要在子类的构造函数中调用 parent::__construct()。如果子类没有定义构造函数则会如同一个普通的类方法一样从父类继承(假如没有被定义为 private 的话)。

    <?php
    class BaseClass {
       function __construct() {
           print "In BaseClass constructor\n";
       }
    }
    
    class SubClass extends BaseClass {
       function __construct() {
           parent::__construct();
           print "In SubClass constructor\n";
       }
    }
    
    class OtherSubClass extends BaseClass {
        // inherits BaseClass's constructor
    }
    
    // In BaseClass constructor
    $obj = new BaseClass();
    
    // In BaseClass constructor
    // In SubClass constructor
    $obj = new SubClass();
    
    // In BaseClass constructor
    $obj = new OtherSubClass();
    ?>
    
    

    void __destruct ( void )

    析构函数会在到某个对象的所有引用都被删除或者当对象被显式销毁时执行。

    <?php
    class MyDestructableClass {
       function __construct() {
           print "In constructor\n";
           $this->name = "MyDestructableClass";
       }
    
       function __destruct() {
           print "Destroying " . $this->name . "\n";
       }
    }
    
    $obj = new MyDestructableClass();
    ?>
    
    

    和构造函数一样,父类的析构函数不会被引擎暗中调用。要执行父类的析构函数,必须在子类的析构函数体中显式调用 parent::__destruct()。此外也和构造函数一样,子类如果自己没有定义析构函数则会继承父类的。

posted @ 2018-07-18 22:03  老婆爱吃炒酸奶  阅读(109)  评论(0)    收藏  举报