『PHP Manual』読書ノート3——類と対象

51933 ワード

1、PHPのすべての関数とクラスはグローバルな役割ドメインを持っていて、一つの関数の中で定義して外で呼び出すことができて、逆も同様です.
PHPは関数のリロードをサポートしていないし、宣言された関数の定義をキャンセルしたり再定義したりすることはできません.
  • 関数が条件付きで定義されている場合、関数を呼び出す前に定義する必要があります.
  • 関数名は大文字と小文字は関係ありませんが、関数を呼び出すときは定義時と同じ形式を使うのが良い習慣です.

  • 2、デフォルト値は定数式でなければなりません.変数、クラスメンバー、関数呼び出しなどではありません.
    デフォルトパラメータを使用する場合は、デフォルト以外のパラメータの右側にデフォルトパラメータを配置する必要があります.そうでなければ、関数は予想通りに動作しません.次のコード・スライスを考慮します.
    php
    function makeyogurt($type = "acidophilus", $flavour)
    {
        return "Making a bowl of $type $flavour.
    "; } echo makeyogurt("raspberry"); // won't work as expected ?>

    以上のルーチンが出力します.
    Warning: Missing argument 2 in call to makeyogurt() in 
    /usr/local/etc/httpd/htdocs/phptest/functest.html on line 41
    Making a bowl of raspberry .

    3、PHPは可変関数の概念をサポートする.これは、変数名の後にカッコが付いている場合、PHPは変数の値と同じ名前の関数を探して実行しようとすることを意味します.可変関数は、コールバック関数、関数テーブルを含むいくつかの用途を実現するために使用できます.静的メソッドを呼び出す場合、関数呼び出しは静的プロパティよりも優先されます.
    可変関数は、echo、print、unset()、isset()、empty()、include、requireなどの言語構造では使用できません.これらの構造を可変関数として使用するには、独自のパッケージ関数を使用する必要があります.
    php
    class Foo
    {
        function Variable()
        {
            $name = 'Bar';
            $this->$name(); // This calls the Bar() method
        }
    
        function Bar()
        {
            echo "This is Bar";
        }
    }
    
    $foo = new Foo();
    $funcname = "Variable";
    $foo->$funcname();   // This calls $foo->Variable()
    
    ?> 

    4、閉パッケージは、親の役割ドメインから変数を継承できます.このような変数はuse言語構造で伝達されるべきです.
    php
    $message = 'hello';
    
    //    "use"
    $example = function () {
        var_dump($message);
    };
    echo $example();
    
    //    $message
    $example = function () use ($message) {
        var_dump($message);
    };
    echo $example();
    
    // Inherited variable's value is from when the function
    // is defined, not when called
    $message = 'world';
    echo $example();
    
    // Reset message
    $message = 'hello';
    
    // Inherit by-reference
    $example = function () use (&$message) {
        var_dump($message);
    };
    echo $example();
    
    // The changed value in the parent scope
    // is reflected inside the function call
    $message = 'world';
    echo $example();
    
    // Closures can also accept regular arguments
    $example = function ($arg) use ($message) {
        var_dump($arg . ' ' . $message);
    };
    $example("hello");
    ?> 

    出力:
    Notice: Undefined variable: message in /example.php on line 6
    NULL
    string(5) "hello"
    string(5) "hello"
    string(5) "hello"
    string(5) "world"
    string(11) "hello world"

    5.あるクラスは、宣言でextendsキーワードで別のクラスのメソッドと属性を継承することができる.PHPは多重継承をサポートしておらず、1つのクラスは1つのベースクラスしか継承できません.
    継承されたメソッドとプロパティは、同じ名前で上書きされることを再宣言できます.ただし、親定義メソッドでfinalが使用されている場合は、このメソッドは上書きできません.parent::を使用して、上書きされたメソッドまたはプロパティにアクセスできます.
    上書き方法の場合、パラメータは一致しなければならない.そうしないと、PHPはE_STRICTレベルのエラーメッセージを発行する.しかし、コンストラクション関数は例外であり、コンストラクション関数はオーバーライド時に異なるパラメータを使用することができる.
    オブジェクトが作成したインスタンスを新しい変数に割り当てると、新しい変数は同じインスタンスにアクセスし、そのオブジェクトで値を割り当てるのと同じになります.この動作は、関数にインスタンスを渡すときと同じです.クローンを使用して、作成したオブジェクトに新しいインスタンスを作成できます.
    php
    
    $instance = new SimpleClass();
    
    $assigned   =  $instance;
    $reference  =& $instance;
    
    $instance->var = '$assigned will have this value';
    
    $instance = null; // $instance and $reference become null
    
    var_dump($instance);
    var_dump($reference);
    var_dump($assigned);
    ?> 

    以上のルーチンが出力します.
    NULL
    NULL
    object(SimpleClass)#1 (1) {
       ["var"]=>
         string(30) "$assigned will have this value"
    }

    PHP 5.5より,キーワードclassはクラス名の解析にも利用できる.ClassName::classを使用すると、クラスClassNameの完全修飾名を含む文字列を取得できます.これは、ネーミングスペースを使用したクラスに特に役立ちます.
    php
    namespace NS {
        class ClassName {
        }
        
        echo ClassName::class;
    }
    ?> 
    NS\ClassName

    6、 " ", " "、" ", " "。 publicprotected private , 。 , PHP , 。

    ->( ):$this->property( property ) 。 ::( ):self::$property 。

    php
    class SimpleClass
    {
       //        
       public $var1 = 'hello ' . 'world';
       public $var2 = <<<EOD
    hello world
    EOD;
       public $var3 = 1+2;
       public $var4 = self::myStaticMethod();
       public $var5 = $myVar;
    
       //        
       public $var6 = myConstant;
       public $var7 = array(true, false);
    
       //  PHP 5.3.0    ,        
       public $var8 = <<
    hello world
    EOD;
    }
    ?> 

    7、 。 , parent::__construct()。 ( private )。

    php
    class BaseClass {
       function __construct() {
           print "In BaseClass constructor
    "; } } class SubClass extends BaseClass { function __construct() { parent::__construct(); print "In SubClass constructor
    "; } } 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(); ?>

    , 。 , parent::__destruct()。 , 。

    exit() 。 exit() 。

    8、public( ),protected( ) private( ) 。 。 。 。

    。 。

    php
    class Test
    {
        private $foo;
    
        public function __construct($foo)
        {
            $this->foo = $foo;
        }
    
        private function bar()
        {
            echo 'Accessed the private method.';
        }
    
        public function baz(Test $other)
        {
            // We can change the private property:
            $other->foo = 'hello';
            var_dump($other->foo);
    
            // We can also call the private method:
            $other->bar();
        }
    }
    
    $test = new Test('test');
    
    $test->baz(new Test('other'));
    ?> 

    string(5) "hello"
    Accessed the private method.

    9、self,parent static 。

    php
    class OtherClass extends MyClass
    {
        public static $my_static = 'static var';
    
        public static function doubleColon() {
            echo parent::CONST_VALUE . "
    "; echo self::$my_static . "
    "; } } $classname = 'OtherClass'; echo $classname::doubleColon(); // PHP 5.3.0 OtherClass::doubleColon(); ?>

    10、 , 。 ( )。 , $this 。

    • -> 。
    • E_STRICTレベルのエラー.

    • のすべてのPHP と に、 は または にのみ され、 は できません.したがって、 プロパティは または に できますが、 の または の り に することはできません.また、オブジェクトを すこともできません.
      php
      class Foo
      {
          public static $my_static = 'foo';
      
          public function staticValue() {
              return self::$my_static;
          }
      }
      
      class Bar extends Foo
      {
          public function fooStatic() {
              return parent::$my_static;
          }
      }
      
      
      print Foo::$my_static . "
      "; $foo = new Foo(); print $foo->staticValue() . "
      "; print $foo->my_static . "
      "; // Undefined "Property" my_static print $foo::$my_static . "
      "; $classname = 'Foo'; print $classname::$my_static . "
      "; // As of PHP 5.3.0 print Bar::$my_static . "
      "; $bar = new Bar(); print $bar->fooStatic() . "
      "; ?> [CDATA[ php class Foo { public static function aStaticMethod() { // ... } } Foo::aStaticMethod(); $classname = 'Foo'; $classname::aStaticMethod(); // PHP 5.3.0 ?>

      11、PHP 5は クラスと をサポートする. として されたクラスはインスタンス できません.いずれのクラスも、 なくとも1つのメソッドが として されている は、このクラスを として する があります. に されたメソッドは、 び し (パラメータ)を するだけで、その な を することはできません.
      クラスを する 、 クラスは クラスのすべての メソッドを する があります.また、これらのメソッドのアクセス は、 と じでなければなりません.(またはそれ の ).たとえば、 メソッドが されていると された 、サブクラスで されるメソッドは、プライベートとして することなく、 されているメソッドまたは されているメソッドとして する があります.また、メソッドの び し は、タイプと なパラメータの が している があります.たとえば、サブクラスはオプションのパラメータを し、 メソッドの にない 、 の は していない.これはPHP 5.4からの にも てはまる.PHP 5.4 のコンストラクタ は なっていてもよい.
      php
      abstract class AbstractClass
      {
       //             
          abstract protected function getValue();
          abstract protected function prefixValue($prefix);
      
          //     (     )
          public function printOut() {
              print $this->getValue() . "
      "; } } class ConcreteClass1 extends AbstractClass { protected function getValue() { return "ConcreteClass1"; } public function prefixValue($prefix) { return "{$prefix}ConcreteClass1"; } } class ConcreteClass2 extends AbstractClass { public function getValue() { return "ConcreteClass2"; } public function prefixValue($prefix) { return "{$prefix}ConcreteClass2"; } } $class1 = new ConcreteClass1; $class1->printOut(); // ConcreteClass1 echo $class1->prefixValue('FOO_') ."
      "; // FOO_ConcreteClass1 $class2 = new ConcreteClass2; $class2->printOut(); // ConcreteClass2 echo $class2->prefixValue('FOO_') ."
      "; // FOO_ConcreteClass2 ?>

      12.インタフェースを するには、implementsオペレータを します.クラスでは、インタフェースで されたすべてのメソッドを する があります.そうしないと、 なエラーが されます.
      クラスは、 のインタフェースを し、 のインタフェースの をカンマで ることができます.
      のインタフェースを する 、インタフェースのメソッドに を けることはできません.
      インタフェースはextendsオペレータを することで することもできます.
      クラスがインタフェースを するには、インタフェースで された と に する を する があります. なエラーが します.
      php
      interface a
      {
          public function foo();
      }
      
      interface b extends a
      {
          public function baz(Baz $baz);
      }
      
      //     
      class c implements b
      {
          public function foo()
          {
          }
      
          public function baz(Baz $baz)
          {
          }
      }
      
      //              
      class d implements b
      {
          public function foo()
          {
          }
      
          public function baz(Foo $foo)
          {
          }
      }
      ?> 

      13、TraitはPHPのような のために されたコード メカニズムである.Traitは, の を らすために, が なる の したクラスでmethodを に できるようにした.TraitとClassの せの は, のマルチ とMixinクラスに する な を する さを する を している.
      php
      trait ezcReflectionReturnInfo {
          function getReturnType() { /*1*/ }
          function getReturnDescription() { /*2*/ }
      }
      
      class ezcReflectionMethod extends ReflectionMethod {
          use ezcReflectionReturnInfo;
          /* ... */
      }
      
      class ezcReflectionFunction extends ReflectionFunction {
          use ezcReflectionReturnInfo;
          /* ... */
      }
      ?> 

      ベースクラスから されたメンバーは、 されたSayWorld TraitのMyHelloWorldメソッドによって きされます.その はMyHelloWorldクラスで された と している. は、 のクラスのメソッドがtraitメソッドを きし、traitメソッドがベースクラスのメソッドを きすることです.
      php
      class Base {
          public function sayHello() {
              echo 'Hello ';
          }
      }
      
      trait SayWorld {
          public function sayHello() {
              parent::sayHello();
              echo 'World!';
          }
      }
      
      class MyHelloWorld extends Base {
          use SayWorld;
      }
      
      $o = new MyHelloWorld();
      $o->sayHello();
      ?> 

      のtraitに じ のメソッドが されている 、 を に しないと なエラーが します. のtraitの じクラスでのネーミング を するには、insteadofオペレータを して、 メソッドのどちらを するかを に する があります. の では、 のメソッドのみを できます.asオペレータは、 するメソッドの1つを の で できます.
      php
      trait A {
          public function smallTalk() {
              echo 'a';
          }
          public function bigTalk() {
              echo 'A';
          }
      }
      
      trait B {
          public function smallTalk() {
              echo 'b';
          }
          public function bigTalk() {
              echo 'B';
          }
      }
      
      class Talker {
          use A, B {
              B::smallTalk insteadof A;
              A::bigTalk insteadof B;
          }
      }
      
      class Aliased_Talker {
          use A, B {
              B::smallTalk insteadof A;
              A::bigTalk insteadof B;
              B::bigTalk as talk;
          }
      }
      ?> 

      traitが を している 、クラスは じ の を できません.そうしないと、エラーが します.クラス の の がtrait の と がある ( じ と )、エラーのレベルはE_STRICTです.そうでない 、 なエラーです.
      14、PHPが する「オーバーロード」(overloading)とは、クラス とメソッドを に「 」することを する. はマジックメソッド(magic methods)によって される.
      PHPの「リロード」は、 のほとんどのオブジェクト け とは なります. のリロードは、 じ のクラスメソッドを するために されていますが、 メソッドのパラメータタイプと は なります.
      15、PHP 5は、 えばforeach を いてセルリストを して できるようにオブジェクトを する を する. では、すべての アトリビュートがループに されます.
      php
      class MyClass
      {
          public $var1 = 'value 1';
          public $var2 = 'value 2';
          public $var3 = 'value 3';
      
          protected $protected = 'protected var';
          private   $private   = 'private var';
      
          function iterateVisible() {
             echo "MyClass::iterateVisible:
      "; foreach($this as $key => $value) { print "$key => $value
      "; } } } $class = new MyClass(); foreach($class as $key => $value) { print "$key => $value
      "; } echo "
      "; $class->iterateVisible(); ?> // var1 => value 1 var2 => value 2 var3 => value 3 MyClass::iterateVisible: var1 => value 1 var2 => value 2 var3 => value 3 protected => protected var private => private var

      16、__construct(), __destruct(), __call(), __callStatic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __toString(), __invoke(), __set_state(), __clone()と_debugInfo()などのメソッドはPHPでは「マジックメソッド」(Magic methods)と ばれています.マジック を したい を き、 のクラスメソッドに を ける は できません.
      PHPはすべて_(2つの ) のクラスメソッドはマジックメソッドとして されます.したがって、クラスメソッドを する には、 のマジックメソッド に__を としないことをお めします.
      17、PHP 5にfinalキーワードが されました. クラスのメソッドがfinalとして されている 、 クラスはメソッドを きできません.クラスがfinalとして されている は、 できません.
      php
      class BaseClass {
         public function test() {
             echo "BaseClass::test() called
      "; } final public function moreTesting() { echo "BaseClass::moreTesting() called
      "; } } class ChildClass extends BaseClass { public function moreTesting() { echo "ChildClass::moreTesting() called
      "; } } // Results in Fatal error: Cannot override final method BaseClass::moreTesting() ?>

      18、PHP 5の はPHP 4より であり、 の は に する.
      (==)を して2つのオブジェクト を する 、 の は、2つのオブジェクトの と が しく、2つのオブジェクトが じクラスのインスタンスである 、2つのオブジェクト が しいことです.
      、 (===)を する 、この2つのオブジェクト は、クラスの じインスタンス(つまり じオブジェクト)を す があります.
      php
      function bool2str($bool)
      {
          if ($bool === false) {
              return 'FALSE';
          } else {
              return 'TRUE';
          }
      }
      
      function compareObjects(&$o1, &$o2)
      {
          echo 'o1 == o2 : ' . bool2str($o1 == $o2) . "
      "; echo 'o1 != o2 : ' . bool2str($o1 != $o2) . "
      "; echo 'o1 === o2 : ' . bool2str($o1 === $o2) . "
      "; echo 'o1 !== o2 : ' . bool2str($o1 !== $o2) . "
      "; } class Flag { public $flag; function Flag($flag = true) { $this->flag = $flag; } } class OtherFlag { public $flag; function OtherFlag($flag = true) { $this->flag = $flag; } } $o = new Flag(); $p = new Flag(); $q = $o; $r = new OtherFlag(); echo "Two instances of the same class
      "; compareObjects($o, $p); echo "
      Two references to the same instance
      "; compareObjects($o, $q); echo "
      Instances of two different classes
      "; compareObjects($o, $r); ?> // Two instances of the same class o1 == o2 : TRUE o1 != o2 : FALSE o1 === o2 : FALSE o1 !== o2 : TRUE Two references to the same instance o1 == o2 : TRUE o1 != o2 : FALSE o1 === o2 : TRUE o1 !== o2 : FALSE Instances of two different classes o1 == o2 : FALSE o1 != o2 : TRUE o1 === o2 : FALSE o1 !== o2 : TRUE

      19、phpの は であり、2つの なる の が じ を す.php 5では、オブジェクト はオブジェクト の を しません. のオブジェクトコンテンツにアクセスするために を するだけです.オブジェクトがパラメータとして され、 として されたり、 の に が り てられたりします. の は の ではありませんが、 じ のコピーが されています.この は じオブジェクトの の を します.
      php
      class A {
          public $foo = 1;
      }  
      
      $a = new A;
      $b = $a;     // $a ,$b           
                   // ($a) = ($b) = 
      $b->foo = 2;
      echo $a->foo."
      "; $c = new A; $d = &$c; // $c ,$d // ($c,$d) = $d->foo = 2; echo $c->foo."
      "; $e = new A; function foo($obj) { // ($obj) = ($e) = $obj->foo = 2; } foo($e); echo $e->foo."
      "; ?> // 2 2 2