>백엔드 개발 >PHP 튜토리얼 >PHP 객체 지식 요약

PHP 객체 지식 요약

墨辰丷
墨辰丷원래의
2018-05-24 10:02:321462검색

이 글은 주로 PHP 객체에 관련된 지식을 요약한 관련 정보를 소개합니다. 필요한 친구들은 참고하면 됩니다.

객체 전달: "PHP 객체는 참조로 전달됩니다"라고 말하는 것이 더 정확한 표현입니다. 그것은 별칭(식별자) 전송입니다. 즉, 모두 동일한 개체의 실제 콘텐츠를 가리키는 동일한 식별자(ID)의 복사본을 저장합니다.

 <?php
 class A {
   public $foo = 1;
 } 
 
 $a = new A;
 $b = $a;   // $a ,$b都是同一个标识符的拷贝
       // ($a) = ($b) = <id>
 $b->foo = 2;
 echo $a->foo."\n";//2

 $c = new A;
 $d = &$c;  // $c ,$d是引用
       // ($c,$d) = <id>
 
 $d->foo = 2;
 echo $c->foo."\n";//2
 
 $e = new A;
 
 function foo($obj) {
   // ($obj) = ($e) = <id>
   $obj->foo = 2;
 }
 
 foo($e);
 echo $e->foo."\n";//2

•객체 복사: 복제 키워드를 통해 객체 복사를 완료할 수 있습니다. 원본 객체가 __clone() 메서드를 정의하면 복사 후 새 객체의 __clone() 메서드가 호출됩니다. ) 메소드를 사용하여 복사된 객체의 속성 값을 수정할 수 있습니다. 객체가 복사되면 객체의 모든 속성에 대해 단순 복사가 수행되지만 모든 참조 속성은 여전히 ​​원래 변수에 대한 참조입니다.

 <?php
 class SubObject
 {
   static $instances = 0;
   public $instance;
 
   public function __construct()
   {
     $this->instance = ++self::$instances;
   }
 
   public function __clone()
   {
     $this->instance = ++self::$instances;
   }
 }
 
 class MyCloneable
 {
   public $object1;
   public $object2;
 
   function __clone()
   {
     // 强制复制一份this->object, 否则仍然指向同一个对象
     $this->object1 = clone $this->object1;
   }
   
   function cloneTest()
   {
     echo &#39;cloneTest&#39;;
   }
 }
 
 $obj = new MyCloneable();
 
 $obj->object1 = new SubObject();
 $obj->object2 = new SubObject();
 
 $obj2 = clone $obj;
 
 print("Original Object:\n");
 print_r($obj);
 
 print("Cloned Object:\n");
 print_r($obj2);
 echo $obj2->cloneTest().":\n";
 echo (new Reflectionclass($obj2));

위 예제의 출력 결과:

Original Object:
MyCloneable Object
(
  [object1] => SubObject Object
    (
      [instance] => 1
    )

  [object2] => SubObject Object
    (
      [instance] => 2
    )

)
Cloned Object:
MyCloneable Object
(
  [object1] => SubObject Object
    (
      [instance] => 3
    )

  [object2] => SubObject Object
    (
      [instance] => 2
    )

)
cloneTest:
Class [ <user> class MyCloneable ] {
 @@ /public/t.php 18-33

 - Constants [0] {
 }

 - Static properties [0] {
 }

 - Static methods [0] {
 }

 - Properties [2] {
  Property [ <default> public $object1 ]
  Property [ <default> public $object2 ]
 }

 - Methods [2] {
  Method [ <user> public method __clone ] {
   @@ /public/t.php 23 - 27
  }

  Method [ <user> public method cloneTest ] {
   @@ /public/t.php 29 - 32
  }
 }
}

•객체 순회: foreach는 객체의 표시 속성만 순회할 수 있지만 해당 메서드는 순회할 수 없습니다. 이는 구현하기 더 쉽습니다. 또한 Iterator 인터페이스를 구현할 수도 있습니다. 또는 IteratorAggregate 인터페이스의 메서드가 개체 속성을 탐색할 수도 있습니다.

•유형 제약 조건: PHP는 약한 유형의 언어입니다. 유형 제약 조건은 프로그래밍을 더욱 표준화하고 오류를 줄일 수 있습니다. 유형 제약 조건은 객체 정의뿐만 아니라 함수 정의에서도 사용할 수 있습니다. 유형 제약 조건은 객체, 인터페이스, 배열 및 콜러블(클로저 콜백)을 지정할 수 있습니다. 유형 제약 조건은 실제 데이터 유형이 프로토타입 정의와 일치하는지 확인하는 데 사용됩니다. 기본값은 NULL입니다. 그러면 실제 매개변수는 NULL이 될 수 있습니다. int 또는 string과 같은 스칼라 유형에는 유형 제약 조건을 사용할 수 없으며 특성도 마찬가지입니다.

•객체 직렬화 및 복원: serialize() 함수는 객체를 쉽게 저장할 수 있도록 바이트 스트림이 포함된 문자열을 문자열로 변환할 수 있으며, unserialize() 함수는 문자열을 객체로 복원할 수 있습니다. 하지만 직렬화, 역직렬화와 상관없이 객체의 클래스 정의가 완료되었다는 전제가 있습니다. 즉, 클래스(파일)을 먼저 임포트해야 합니다.

•오버로딩: PHP의 오버로딩에는 관용구에 가깝습니다. 이는 예측할 수 없으며 더 넓은 영향을 미치는 클래스 속성입니다. 현재 환경에서는 정의되지 않았거나 보이지 않습니다. 오버로드된 모든 메서드는 공개로 선언해야 합니다(이해하기가 더 쉬워야 합니다. 보이지 않기 때문에 다른 사람이 필요할 수 있으므로 사용자도 표시되어야 함). 매개 변수는 참조로 전달할 수 없습니다. 오버로드된 메서드는 예측할 수 없습니다. 보안상의 이유로 방지할 수 없습니다. 변수는 마음대로 참조되지 않습니다). 오버로드된 속성은 isset()을 제외하고 다른 언어 구성에서 사용할 수 없습니다. 즉, 오버로드된 속성에 대해 empty()를 사용할 때 오버로드된 매직 메서드가 호출되지 않습니다. 이 제한을 피하기 위해서는 오버로드된 속성을 지역 변수에 할당해야 합니다. 그런 다음 유효한 속성과 불법적인 속성 사이에 오버로드된 속성이 존재함을 알 수 있습니다.

[속성 오버로딩]: 이러한 메서드는 정적으로 선언할 수 없습니다. 정적 메서드에서는 이러한 매직 메서드가 호출되지 않습니다.
public void __set(string $name, Mixed $value)
액세스할 수 없는 속성에 값을 할당할 때 __set ()가 호출됩니다

public 혼합 __get ( string $name )
액세스할 수 없는 속성의 값을 읽을 때 __get()이 호출됩니다

public bool __isset ( string $name )
액세스할 수 없는 속성에 대해 호출되는 경우 isset() 또는 empty(), __isset()가 호출됩니다

public void __unset ( string $name )
접근할 수 없는 속성에 대해 unset()이 호출되면 __unset()이 호출됩니다

참고:
PHP가 할당 작업이 처리되는 방식에서는 __set()의 반환 값이 무시됩니다. 마찬가지로 다음 체인 할당에서는 __get()이 호출되지 않습니다.
$a = $obj->b = 8;

[메소드 오버로딩]:
public 혼합 __call ( 문자열 $name , 배열 $arguments )
객체에서 접근할 수 없는 메소드가 호출되면 __call()이 호출됩니다

public static mix __callStatic ( string $name , array $arguments )
접근할 수 없는 메소드가 정적 컨텍스트에서 호출되면 __callStatic( )이 호출됩니다

•정적 속성 및 메서드: 정적 키워드는 정적 속성과 정적 메서드를 정의하는 데 사용됩니다. 정적 속성은 인스턴스화된 개체를 통해 액세스할 수 없습니다(그러나 정적 메서드는 가능함). 정적 속성은 상수 표현식으로만 초기화할 수 있으므로 정적 속성은 정수나 배열로 초기화할 수 있지만 다른 변수나 함수 반환 값으로 초기화할 수 없으며 객체를 가리킬 수도 없습니다. 변수를 사용하여 클래스를 나타내면 정적 속성을 동적으로 호출할 수 있지만 변수 값은 키워드 self, parent 또는 static이 될 수 없습니다.

 class Foo
 {
   public static $my_static = &#39;foo&#39;;
 
   public function staticValue() {
     return self::$my_static;
   }
 }
 
 class Bar extends Foo
 {
   public function fooStatic() {
     return parent::$my_static;
   }
 }
 
 
 print Foo::$my_static . "\n";
 
 $foo = new Foo();
 print $foo->staticValue() . "\n";
 print $foo->my_static . "\n";   // Undefined "Property" my_static 
 
 print $foo::$my_static . "\n";
 $classname = &#39;Foo&#39;;
 print $classname::$my_static . "\n"; // As of PHP 5.3.0
 
 print Bar::$my_static . "\n";
 $bar = new Bar();
 print $bar->fooStatic() . "\n";

•后期静态绑定:static:: 定义后期静态绑定工作原理是存储了上一个“非转发调用”(non-forwarding call)的类名。当进行静态方法调用时,该类名即为明确指定的那个(通常在 :: 运算符左侧部分);当进行非静态方法调用时,即为该对象所属的类。使用 self:: 或者 __CLASS__ 对当前类的静态引用,取决于定义当前方法所在的类;static:: 不再被解析为定义当前方法所在的类,而是在实际运行时计算的,可以用于静态属性和所有方法的调用。

 <?php
 class A
 {
   
   private $proPrivate = "private of A";
   protected $proProtected = "protected of A";
   public $proPublic = "public of A";
   
   private function foo()
   {
     echo $this->proPrivate."\n";
     echo $this->proProtected."\n";
     echo $this->proPublic."\n";
   }
   
   public function test()
   {
     $this->foo();
     static::foo();
   }
 }
 
 class B extends A
 {
  /* foo() will be copied to B, hence its scope will still be A and
   * the call be successful */
 }
 
 class C extends A
 {
   private $proPrivate = "private of C";
   protected $proProtected = "protected of C";
   public $proPublic = "public of C";
   
   private function foo()
   {
     /* original method is replaced; the scope of the new one is C */
     echo "I am C\n";
   }
   
   public function myFoo()
   {
     //parent::foo();
     $this->foo();
   }
 }
 
 echo "Class B:\n";
 $b = new B();
 $b->test();
 echo "\nClass C:\n";
 $c = new C();
 $c->myFoo();
 $c->test();  //fails

上例输出结果:

Class B:
private of A
protected of A
public of A
private of A
protected of A
public of A

Class C:
I am C
private of A
protected of C
public of C 
Fatal error: Uncaught Error: Call to private method C::foo() from context &#39;A&#39; in /public/t.php:19 Stack trace: #0 /public/t.php(54): A->test() #1 {main} thrown in /public/t.php on line 19

•继承:官方文档对继承有这样一段描述“当扩展一个类,子类就会继承父类所有公有的和受保护的方法。除非子类覆盖了父类的方法,被继承的方法都会保留其原有功能”,言下之意似乎私有属性和方法不会被继承;然而上例又告诉我们子类拥有与父类一致的属性和方法,继承就是全盘复制,这才能满足我们对继承编程的需求,如果私有的不能继承,子类就必须自行重新定义,在大多数时候没有必要。另外就是可见性问题,父类的私有属性和方法在子类是不可见的。上例还告诉我们对象实际执行的域要考虑可见性、继承、后期静态绑定机制。

以上就是本文的全部内容,希望对大家的学习有所帮助。


相关推荐:

PHP表单数据写入MySQL数据库的代码

php基于登陆时间判断实现一天多次登录只积分一次功能

php 三元运算符实例详细介绍

위 내용은 PHP 객체 지식 요약의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.