<?php
/**
* Created by PhpStorm.
* User: cl
* Date: 2019/8/12
* Time: 7:08
*/
/*oop*/
class Person{
public $name;
public $gender;
public function say(){
echo $this->name,'is',$this->gender;
}
} $student = new Person();
$student->name = "CL";
$student->gender = "MAN";
$student->say();
// CLisMAN
var_dump((array)$student);
// array(2) { ["name"]=> string(2) "CL" ["gender"]=> string(3) "MAN" }
// 对象由属性组成,一个对象的属性是它区别于另一个对象的关键所在。由于php的对象使用数组来模拟的
// 因此我们把对象转成数组,就能看见这个对象所拥有的属性了。
// 到这里,可以直观的认识到,对象就是一堆数据。既然如此,可以把一个对象存储起来,以便需要时用,这就是对象的序列化。
$str = serialize($student);
var_dump($str);
// string(60) "O:6:"Person":2:{s:4:"name";s:2:"CL";s:6:"gender";s:3:"MAN";}"
// 在需要时,可以反序列化取出这个对象
var_dump(unserialize($str));
// object(Person)#2 (2) { ["name"]=> string(2) "CL" ["gender"]=> string(3) "MAN" }
// 可以看到,对象序列化后,存储的只是对象的属性。类是由属性和方法组成的,而对象则是属性的集合,由同一个类生成的不同对象,
// 拥有各自不同的属性,但共享了类的代码空间中方法区域的代码。 /*对象与数组*/
// 数组是由键值对数据组成,数组的键值对和对象的属性/属性值对十分相似。对象序列化后和数组序列化后的结果是
// 惊人的相似
$student_arr = ['name' => 'CL' , 'gender' => 'MAN'];
var_dump(serialize($student_arr));
// string(49) "a:2:{s:4:"name";s:2:"CL";s:6:"gender";s:3:"MAN";}"
// 区别在于 : 对象中还包含指针,指向了它所属的类。 /* 对象与类*/
// 如果对象中还包含对象,那么序列化后会是什么样子呢?
class Family{
public $people;
public $location;
public function __construct ($p,$loc){
$this->people = $p;
$this->location = $loc;
}
/* public function __destruct(){
var_dump('魔术方法之析构方法');
}*/
}
$tom = new Family($student,"peking");
var_dump(serialize($tom));
// string(118) "O:6:"Family":2:{s:6:"people";O:6:"Person":2:{s:4:"name";s:2:"CL";s:6:"gender";s:3:"MAN";}s:8:"location";s:6:"peking";}"
/* 可以看出,序列化后的对象会附带所属类型,这个类名保证此对象在执行类的方法(也是自己所能执行的方法)时,
能够正确地找到方法所在的代码空间(即对象所拥有的方法存储在类里)。另外,当一个对象的实例变量引用其他对象时,序列化对象
也会对引用对象进行序列化
由此可以分析二者的关系 :
类是定义一系列属性和操作的模板,而对象则是把属性进行具体化,然后交给类处理
对象就是数据,对象本身包含方法。但是对象有一个”指针“指向一个类,这个类里可以有方法。
方法描述不同属性导致的不同表现
类和对象是不可分割的,有对象就必定有一个类与其对应,否则这个对象也就成了没有亲人的孩子(但有一个特殊的情况,就是
由标量进行强制类型转换的object,没有一个类与它对应。此时,PHP中一个称为”孤儿“的stdClass类就会收留这个对象)
可以看出,在面向对象层面,js和php区别还是很大的。
*/ /*魔术方法*/
/*
* 魔术方法是以两个下划线开头,具有特殊作用的一些方法,可以看作是PHP的语法糖
* 语法糖是指那些没有给计算机添加新功能,而对人类来说更甜蜜的语法
* Family类的__construct方法就是一个标准的魔术方法。这个魔术方法又称构造方法。具有构造方法的类会每次创建对象时
* 先调用此方法,所以非常适合在使用对象之前做一些初始化工作,如:给属性赋值,连接数据库等
* 有构造方法就有析构方法,即destruct方法,这个方法会在某个对象的所以引用都被删除,或者当对象被显式销毁时执行。
* 这两个方法是最常见也是最有用的魔术方法
*/
/*魔术方法之set 和 get*/
class Account{
private $user = 1;
private $pwd = 2; public function __get($name){
echo '请求'.$name;
}
public function __set($name,$val){
echo "请求设置".$name."为".$val;
} public function __call($name ,$arguments){
// $name : 要调用的方法名称
// $arguments : 数组,包含着要传递给方法的参数
var_dump($name);
var_dump($arguments);
}
public static function __callStatic($name ,$arguments){
var_dump($name);
var_dump($arguments);
}
public function __toString()
{
return '任意字符串';
} }
$a = new Account();
$a->user; // 如果没有 __get 魔术方法则会报错,大致意思是不能访问对象的私有属性
// 请求user
$a->name = '123'; // 因为对象没有name属性,所以会触发 __set 魔术方法
// 请求设置name为123
/*
* 可以直观的看到,若类中定义了set 和 get这一对魔术方法,那么当给对象属性赋值或取值时,即使
* 这个属性不存在,也不会报错,一定程度上增强了程序的健壮性
*/
// 那么,如果防止调用一个不可访问的方法(如未定义,或者不可见)时,call()会被调用。
$a->demo('1','2');
// "demo"
// array(2) { [0]=> string(1) "1" [1]=> string(1) "2" }
// 当调用的静态方法不存在或权限不足时,callStatic() 会被调用
Account::demo();
// "demo"
// array(0) { } // 当然,使用魔术方法"防止调用不存在的方法而报错",并不是魔术方法的本意。实际上,魔术方法使方法的动态创建变为可能。
// 这在MVC等框架设计中是很有用的语法。可以通过一段代码使用callStatic这一魔术方法进行方法的动态创建和延迟绑定 // toString方法
echo $a; //任意字符串
// 比如打印一个对象时,看看这个对象都有哪些属性,其值是什么,如果定义了toString方法,就能在测试时,echo打印对象体
// 对象会自动调用它所属类定义的toString方法,格式化输出这个对象所包含的数据。如果没有这个方法,那么echo一个对对象将报错
<?php
/**
* Created by PhpStorm.
* User: chenglin
* Date: 2019/8/12
* Time: 7:08
*/
/*oop高级*/
class Person{
public $name = 'tom';
public $gender;
public $money = 1000;
public function __construct(){
echo '这里是父类'; }
public function say(){
var_dump( $this->name);
}
}
class Family extends Person{
public $name;
public $gender;
public $money = 100000;
public function __construct(){
parent::__construct();
echo "这里是子类";
}
public function say(){
parent::say();
}
} $poor = new Family();
$poor->say();
// 这里是父类
// 这里是子类
// NULL /*
* 从上面的代码中可以了解继承的实现。在继承中,用parent指代父类,用self指代自身。
* 使用"::"操作符(范围解析操作符)调用父类的方法。"::"操作符还可以作为类常量和静态方法的调用,不要把这两种应用混淆。
* 既然提到静态,就再强调一点。如果声明类成员或方法为static,就可以不实例化类而直接访问
*/
/*接口*/
/*
* 这里,首先强调一个概念,面向接口编程并不是一种新的编程范式。本章开头提到的三大范式中并没有提到面向接口。其实,
* 这里是狭义的接口,即 interface 关键字。广义的接口可以是任何一个对外提供服务的出口,比如提供数据传输的usb接口,
* 、淘宝网对其他网站开放的支付宝接口。
* 接口定义一套规范,描述一个"物"的功能,要求如果现实中的"物"想成为可用,就必须实现这些基本功能。接口这样描述自己:
* "对于实现我的所以类,看起来都应该向我现在这个样子"
* 在程序中,接口的方法必须被全部实现,否则会报fetal错误
*/
interface mobile{
public function run(); // 驱动方法
}
class plain implements mobile{
public function run()
{
// TODO: Implement run() method.
echo "我是飞机";
}
public function fly(){
echo "飞行";
}
}
(new plain())->fly();
// 飞行
// 思考: 接口本身并不提供实现,只要提供一个规范。
// php中,接口的语义是有限的,使用接口的地方并不多,php中接口可以淡化为设计文档,起到一个团队基本契约的作用
// 由于php是弱类型,且强调灵活,所以并不推荐大规模使用接口,而仅在部分"内核"代码中使用接口。从语义上考虑,
// 可以更多地使用抽象类 //抽象类
abstract class Fruits{
// 水果名称
protected $name;
// 抽象方法
abstract public function eat();
// 尽管不能实例化抽象类,但仍然可以有构造方法
public function __construct(){
echo "抽象构造器,实例化时自动调用" ;
}
}
class Apple extends Fruits{
protected $name = "苹果";
public function eat(){
echo $this->name . "可以直接生吃";
}
// 子类构造方法
public function __construct()
{
echo parent::__construct();
}
}
$apple = new Apple();
echo $apple->eat();
// 抽象构造器,实例化时自动调用
// 苹果可以直接生吃 // 抽象类提供了具体实现的标准,而接口则是纯粹的模板 /*反射*/
/*
* 面向对象编程中对象被赋予了自省的能力,而这个自省的过程就是反射。
* 反射,直观理解就是根据到达地找到出发地和来源。比方说:我给你一个光秃秃的对象,我可以
* 仅仅通过这个对象就能直到它所属的类,拥有哪些方法
*/ // 反射API
$reflect = new ReflectionObject($apple);
// 获取对象属性列表
$props = $reflect->getProperties();
foreach ($props as $prop){
var_dump($prop->getName());
}
// string(4) "name"
// 获取对象的方法列表
$m = $reflect->getMethods();
foreach ($m as $prop){
var_dump($prop->getName());
}
// string(3) "eat"
// string(11) "__construct" // 也可以不用反射API,使用class函数,返回对象属性的关联数组以及更多信息
var_dump(get_object_vars($apple)); // 返回对象属性的关联数组
// array(0) { }
var_dump(get_class_vars(get_class($apple))); // 类属性
// array(0) { }
var_dump(get_class_methods(get_class($apple))); // 返回由类的方法名组成的数组
// array(2) { [0]=> string(3) "eat" [1]=> string(11) "__construct" } // 在此。利用强大的反射API功能范元这个类的原型,包括方法的访问权限:
$obj = new ReflectionClass('Apple');
// 获取类型
$className = $obj -> getName();
// 初始化方法和成量数组
$methods = $properties = [];
foreach ($obj->getProperties() as $v){
$properties[$v->getName()] = $v;
}
foreach ($obj->getMethods() as $v){
$methods[$v->getName()] = $v;
}
echo "<br />class {$className}<br />{<br />";
is_array($properties) && ksort($properties); // 数组排序
// 遍历出类的属性
foreach ($properties as $k => $v){
echo "\t";
echo $v->isPublic() ? 'public' : '',$v->isPrivate() ? 'private' : '',$v->isProtected() ? 'protected' : '',
$v->isStatic() ? 'static' : '';
echo "\t{$k}";
}
// 遍历出类的方法
is_array($methods) && ksort($methods); // 数组排序
foreach ($methods as $k => $v){
echo "<br />function $k(){}";
}
echo "<br / >}"; /*
class Apple{
protected name
function __construct(){}
function eat(){}
}
*/
/*
* 反射的作用: 用于文档生成。因此可以用它对文件里的类进行扫描,逐个生成描述文档
*

php核心技术与最佳实践--- oop的更多相关文章

  1. PHP核心技术与最佳实践——全局浏览

    难得买到并喜欢一本好书,‘PHP核心技术与最佳实践’. 几天时间,先看了个大概,总结一下整体是什么样子的,怎么看怎么学. 1.总共14章: 2.第1.2章讲PHP的OOP: 其中第一章侧重于PHP的O ...

  2. 温习《PHP 核心技术与最佳实践》这本书

    再次看这本书,顺手提炼了一下大致目录,以便后续看见目录就知道大概讲的些什么内容 PHP 核心技术与最佳实践 1.面向对象思想的核心概念 1.1 面向对象的『形』与『本』 1.2 魔术方法的应用 1.2 ...

  3. 《深入理解Java 7核心技术与最佳实践》读书笔记(2) Java语言动态性引言

    Java语言是一种静态类型的编程语言.静态类型的含义是指在编译时进行类型检查.Java源代码中的每个变量的类型都要显式地进行声明.所有变量.方法的参数和方法返回值的类型在程序运行之前就必须是已知的.J ...

  4. PHP核心技术与最佳实践--笔记

    <?php error_reporting(E_ALL); /* php 5.3引入 延迟静态绑定 */ /* php5.4引入trait,用来实现多层继承 trait Hello{} trai ...

  5. 《Java核心技术与最佳实践》读书笔记

    第一章 Java7新语法 1.switch中使用字符串 2.增加二进制表示0b10101010:数字字面量允许直径使用下划线12_34_90 3.一个catch字句捕获多个异常,多个异常之间用|分隔 ...

  6. php核心技术与最佳实践(笔记一)

    1.1面向对象的型与本 类是对象的抽象组织,对象是类的具体存在. 1.1.1对象的形 <?php class Person{ public $name; public $gender; publ ...

  7. PHP-PHP核心技术与最佳实践阅读

    1.对象的实质: 对象就是数据, 对象本身不包含方法, 但是对象有一个"指针"指向一个类, 这个类里可以有方法 2.反射是指在PHP运行状态中, 扩展分析PHP程序, 导出或者提取 ...

  8. 模板引擎 引自 《PHP核心技术与最佳实践》

    随着web的发展,仅一门语言或者一种技术已经不能满足需求,分层架构显得越来越重要.在大型架构中,从来不会简单地应用php从头到尾实现一个完整的mvc架构.可能底层是c/java的支撑,负责密集运算和y ...

  9. php核心技术与最佳实践知识点(下)

    九.缓存 1.缓存三大要素:命中率, 缓存更新策略,缓存最大数据量 2.命中率(mysql为例):mysql提供了一系列的query cache的global status来提现数据库缓存的情况: s ...

随机推荐

  1. matlab逐行读取text文件,编写函数提取需要的文字

    在数学建模中遇到的数据比较难处理,而且给的是text格式,自己想了好长时间才编出来,现在分享一下,可以交流学习 目标的text文件是 只提取里面的数据 需要自编函数 clc,clear path='D ...

  2. LeetCode:27 移除元素

    给定一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成 ...

  3. 0009 基于DRF框架开发(02 创建模型)

    上一节介绍了DRF开发的基本流程,共五个步骤: 1 创建模型 2 创建序列化器 3 编写视图 4 配置URL 5 运行测试 本节主要讲解创建模型. 构建学校,教师,学生三个模型,这三个模型之间的关系是 ...

  4. 2级搭建类204-Oracle 12cR2 SI ASM 图形化搭建(RHEL7.6)

    红帽RHEL 7.6上搭建Oracle 12cR2 ASM单实例 我给你们说,不是自家的产品,那贼麻烦,你是不是觉得在 红帽 7.6 上搞 12c ASM 觉得应该/好像/可能/或许/貌似/大概/也许 ...

  5. qsort 与sort 对结构体排序实例

    qsort 与sort 对结构体排序实例 #include<bits/stdc++.h> using namespace std; typedef struct { string book ...

  6. java读取解析application.yml

    java读取解析application.yml 不用依赖spring容器,可单独使用. bug已修改... 第一步.首先要2个jar <!-- properties和yaml格式化 --> ...

  7. 二分查找 python实现

    欢迎回来 [^first blood]. 要求A是升序数组 递归 只能查 数据存不存在,不能返回下标 def binary_find(A, m): if len(A) == 0: return -1 ...

  8. 设置display:inline-block 元素间隙

    上代码: <div class="page"> <a href="" class="num">共1231条</ ...

  9. Visual Studio 问题汇总

    VS2019 16.3.6   1   JSON 文件没有进行格式化验证 开发时运行正常,部署在IIS中有错误提示. 2  .NET Core 3.0 没有提供中文包 所有注释都是英文的.

  10. 使用yum安装报错:[Errno 256] No more mirrors to try

    背景:我使用yum方式安装软件时,比如zabbix这种软件,我们在安装时一般都是直接到zabbix官网,按照官方的步骤进行安装,但是有一个问题,官方的服务器不在国内,时常会在安装时导致超时报错.此时解 ...