第一篇:传智播客 韩顺平 php从入门到精通 61-78讲面向对象课堂笔记
php面向对象编程 提出一个问题?
张老太养了两只猫猫:一只名字叫小白,今年3岁,白色。还有一只叫小花,今年100岁,花色。请编写一个程序,当用户输入小猫的名字时,就显示该猫的名字,年龄,颜色。如果用户输入的小猫名错误,则显示张老太没有这只猫猫。数组<--->对象
array(1,56,90,100)->隐藏问题array(对象,对象。。)【数组对象】 首先我们用现有的知识来完成这个案例:
$cat1_name=”小白”;
$cat1_age=3;
$cat1_color=”白色”;
//变量是分开.$cat2_name=”小花”;
$cat2_age=100;
$cat2_color=”花色”;?>
我们能不能把属于同一事物的变量,统一管理? 解决之道->对象 快速体验案例:
//这就是一个类(猫类)class Cat{
//属性
public $name;
public $age;
public $color;}
//创建一只猫 $cat1=new Cat();//给这只猫赋值.(具体各个)$cat1->name=“小白”;$cat1->age=3;$cat1->color=“白色”;$cat2=new Cat();$cat2->name=“小花”;$cat2->age=100;$cat2->color=“颜色”;//如果我们找到一只猫,只要找到 $cat1, 那么该变量所有相关的属性都通通的找到 $findCatName=“小花”;
if($cat2->name==$findCatName){
echo $cat2->name.“||”.$cat2->age.“||”.$cat2->color;} ?>
我们这里说明一下类和对象的关系(细节后面逐步展开)
总结几句话:
①
类是抽象的,代表一类事物 ②
对象是具体,是类的一个具体实例 ③
类是对象的模板, 对象是类的一个个体实例
php面向对象编程
成员属性的说明
1.成员属性是从某个事物提取出的,它可以是基本数据类型(整数、小数、字符、布尔),也可以是复合数据类型(数组、对象)
class Cat{ public $name;public $age;}
//创建对象
$cat1=new Cat;
$cat1=new Cat();?>
2.怎样访问一个成员属性(其它成员属性是public)基本语法是 $对象名->属性名;
☞如果一个文件,专门用于定义类,则命名规范应当这样
类名.class.php 分析对象在内存中存在的形式 //定义一个人类 class Person{ public $name;public $age;} $a=new Person();$a->name=“小明”;$a->age=20;//把a变量(对象),赋给$b $b=$a;echo $a->name.“
”;echo $b->name.“
”;
再次说明: $a=78;//$b=$a;$b=&$a;$b=$b+8;echo $a.“||”.$b;
如果给一个函数传递一个对象,实际上是传递的一个地址.//看下面的一段代码: class Person{
public $name;public $age;} $p1=new Person();$p1->name=“韩顺平”;$p1->age=33;//函数接收对象时候,究竟是传入值,还是地址(!!)
function test1($p){ $p->name=“小明”;} test1($p1);echo $p1->name;分析图
如果给函数传递的是基本数据类型(整数、小数、布尔、字符),究竟传递的是什么? 结论 : 在默认的情况下是传递的值,如果你希望传入地址 function test(&$变量....){ }
在php中如果,给一个函数传递的是数组,则默认情况下是传值(拷贝了新的数组),如果希望传入地址,则应当,&$数组名 学生问题?
$a1=array(1,3,900);$a2=array(56,90,100);
$arr=array($a1,$a2);
foreach($arr as $k=>$v){
echo “$k=$v”;} ?>
成员方法的讲解 函数和成员方法关系:
当我们把一个函数写到某个类中,则该函数可以称成员方法:
我们有这样一个需求;希望人可以说话, 做算术题.......,这样就需要使用到成员方法: ①添加speak 成员方法,输出我是一个好人
②添加jisuan成员方法,可以计算从 1+..+1000的结果
③修改jisuan成员方法,该方法可以接收一个数n,计算 1+..+n 的结果
④添加add 成员方法,可以计算两个数的和 成员方法的基本语法:
访问修饰符号 function 函数名(参数列表){
//函数体
//return 语句;}
class Person{
public $name;
public $age;
public function speak(){
echo “我是一个好人!”;
}
public function count1(){
$res=0;
for($i=1;$i<=1000;$i++){
$res+=$i;
}
//return 究竟到什么地方去?谁调用,就返回给谁
return $res;
}
//修改jisuan成员方法,该方法可以接收一个数n,计算 1+..+n 的结果
public function count2($n){
$res=0;
for($i=0;$i<=$n;$i++){
$res+=$i;
}
return $res;
}
//添加add 成员方法,可以计算两个数的和
public function add($num1,$num2){
return $num1+$num2;
}
}
//如何使用函数
//1.创建一个人
$p1=new Person();
//通过对象去访问,调用成员方法.//这里强调,调用成员方法和调用普通函数的机制,仍然不变
$p1->speak();
//让这个人做算术题
$res=$p1->count1();
echo '计算结果是='.$res;
//让这个人可以接收一个数,然后计算
echo “计算结果是=”.$p1->count2(100);
echo “计算结果是=”.$p1->count2(100);
echo “计算结果是=”.$p1->count2(100);
echo “23+89=”.$p1->add(23,89);?>
成员方法的细节
我们在实际开发,其实通常是这样来使用类
Person.class.php < ?php
class Person{
//成员属性
public $name;
public $age;
//成员方法
public function speak(){
echo “我是一个好人!”;
}
public function count1(){
$res=0;
for($i=1;$i<=1000;$i++){
$res+=$i;
}
//return 究竟到什么地方去?谁调用,就返回给谁
return $res;
}
//修改jisuan成员方法,该方法可以接收一个数n,计算 1+..+n 的结果
public function count2($n){
$res=0;
for($i=0;$i<=$n;$i++){
$res+=$i;
}
return $res;
}
//添加add 成员方法,可以计算两个数的和
public function add($num1,$num2){
return $num1+$num2;
}
//添加一个新的方法,可以判断三个数最大的数
public function findMax($arr){
//这里仍然可以写算法
//从$arr数组中,找到最大的数.//1.假设数组的第一个数就是最大的数
$maxVal=$arr[0];
//2.最大数的下标是
$maxIndex=0;
//开始循环的比较
for($i=1;$i //这个条件说明,maxVal不是最大 if($maxVal<$arr[$i]){ //调整 $maxVal=$arr[$i]; $maxIndex=$i; } } return $maxVal; } } ?> Exercise01.php < ?php //引入类文件 require_once „Person.class.php‟; //创建对象 $p1=new Person(); //调用$p1的各个方法 $p1->speack(); $p1->count1();..?> 案例:编写一个函数(以面向对象的方式开发),从网页输入一个整数打印出对应的金子塔: 当我们学习完成员方法后,我们的类定义就完善一步了: 1.设计计算机类,要求如下: 属性:品牌,颜色,cpu型号,内存容量,硬盘大小,价格,工作状态 方法: 打开,关闭,休眠(表示)创建一个计算机对象,调用打开,关闭方法.php面向对象编程 构造方法 class Person{ public $name; public $age;} $p1=new Person();//再给属性赋值 $p1->name=”宋江”;$p1->age=33; //需求在创建一个人对象时候,我就初始化 name 和 age;->构造方法 我们快速入门: class Person{ public $name; public $age; public function __construct(){ echo “我是构造方法”; } //业务代码要放在成员方法 public function findPerson(){ } } $p1=new Person();☞构造方法没有返回值, 它是自动被调用 2.在php 5 中一个类可以同时有两种形式的构造方法 __construct()和类名(), 当两个同时存在的时候,优先调用__construct(), 请大家以后使用__construct() this的理解 class Person{ public $name;public $age; //这个就是构造方法,php5独有 public function __construct($iname,$iage){ //$name认为$name是一个新的变量 //$name=$iname; //$age=$iage; $this->name=$iname; $this->age=$iage; echo “我是构造方法”;} } $p1=new Person(“张清”,90);echo “hello-”.$p1->name;$p2=new Person(“宋江”,33);echo “aa-”.$p2->name;$this 理解图: ☞ 1.$this 本质可以理解就是这个对象的地址 2.哪个对象使用到$this, 就是哪个对象地址 3.$this不能在类外部使用.构造方法的注意事项 (1)一旦自定义了一个构造函数,默认的 构造函数就被覆盖了,这时在创建对象的时候就要使用自定义的构造函数.(2)一个类只能有一个构造函数.(不能重载)构造方法的8点说明: ①构造方法名和类名相同(php4版),php5版的构造方法 名可以和类名相同,也可以是__construct()②构造方法没有返回值 ③主要作用是完成对新对象的初始化,并不是创建对象本身。④在创建新对象后,系统自动的调用该类的构造方法 ⑤一个类有且只有一个构造方法,在php5后虽然__construct()和类名()可以共存,但是实际上也只能使用一个。 ⑥如果没有给类自定义构造方法,则该类使用系统默认的构造方法。class Cat{ funciton __construt($name){ echo “ok”;} } $cat1=new Cat(); ⑦如果给类自定义了构造方法,则该类的默认构造方法被覆盖。⑧构造方法的默认访问修饰符是public 析构方法 析构方法的作用主要用于,释放资源(比如释放数据库的链接,图片资源...销毁某个对象..)快速入门 class Person{ public $name; public $age; public $conn; //构造方法 public function __construct($name,$age){ $this->name=$name; $this->age=$age; //打开一个$conn链接数据库的资源 } //写一个析构方法 __ 是两个下划线 function __destruct(){ echo $this->name.“销毁资源关闭数据库.. } } $p1=new Person(“贾宝玉”,16); $p2=new Person(“林黛玉”,14);?> 运行代码我们得出: 1.析构方法会自动调用 2.析构方法主要用于销毁资源 3.析构方法调用顺序是,先创建的对象后被销毁 4.析构方法什么时候被调用(1)当程序(进程结束)退出时 (2)当一个对象称为垃圾对象的时候,该对象的析构方法也会被调用,(3)所谓垃圾对象,就是指,没有任何变量再引用它.(4)一旦一个对象成为垃圾对象,析构方法就会立即调用 示意图: 小结: ①php5加入的的析构方法function __destruct()②析构方法没有返回值 ③主要作用是释放资源的操作,并不是销毁对象本身。④在销毁对象前,系统自动的调用该类的析构方法 ⑤一个类最多只有一个析构方法。 更新时间:2013年01月03日17时03分 来源: 静态变量 提出一个问题: 说,有一群小孩在玩堆雪人,不时有新的小孩加入, 请问如何知道现在共有多少人在玩?请使用面向 对象的思想,编写程序解决。思路: 1.使用全局变量 * 什么是全局变量, 在程序中,都可以使用的变量称为全局变量.当我们了解全局变量后,我们来看看如何解决问题? //定义,完游戏的全局变量 global $global_nums; //赋值 $global_nums=0; class Child{ public $name; function __construct($name){ $this->name=$name; } public function join_game(){ //声明一下使用全局变量 global $global_nums; $global_nums+=1; echo $this->name.“加入堆雪人游戏”; } } //创建三个小孩 $child1=new Child(“李逵”); $child1->join_game(); $child2=new Child(“张飞”); $child2->join_game(); $child3=new Child(“唐僧”); $child3->join_game(); //看看有多少人玩游戏 echo “ 2.使用静态变量 静态的变量的基本用法 1.在类中定义静态变量 [访问修饰符] static $变量名;2.如何访问静态变量 如果在类中访问 有两种方法self::$静态变量名 , 类名::$静态变量名 如果在类外访问: 有一种方法类名::$静态变量名 3.静态变量存在方式 解法: class Child{ public $name; //这里定义并初始化一个静态变量 $nums public static $nums=0; function __construct($name){ $this->name=$name; } public function join_game(){ //self::$nums使用静态变量 self::$nums+=1; echo $this->name.“加入堆雪人游戏”; } } //创建三个小孩 $child1=new Child(“李逵”); $child1->join_game(); $child2=new Child(“张飞”); $child2->join_game(); $child3=new Child(“唐僧”); $child3->join_game(); //看看有多少人玩游戏 echo “ 静态方法 需求: 当我们操作静态变量的时候,我们可以考虑使用静态方法,比如统计所有学生交的学费 在我们编程中,我们往往使用静态方法去操作静态变量.静态方法的特点 1.静态方法去操作静态变量 2.静态方法不能操作非静态变量.这里请注意 : 普通的成员方法,既可以操作非静态变量,也可以操作静态变量 php面向对象编程的三大特征 ① 封装 ② 继承 ③ 多态 抽象 class Account { public $blance; public $no; public function qun(){ } public function cun(){ } } 封装 那么在php中如何实现这种类似的控制呢?请大家看一个小程序.(visit1.php),不能随便查看人的年龄,工资等隐私...class Person{ public $name; private $age; private $salary; function __construc($name,$age,$salary){ $this->name=$name; $this->age=$age; $this->salary=$salary } } php提供了三种访问控制符号.有三种 1.public 表示全局,可以在本类,类外部,子类中使用 2.protected 表示受到保护,可以在本类, 子类中使用 3.private 表示私有, 只能在本类使用 这三个控制修饰符号可以对属性和方法修饰 1.如果一个方法没有访问修饰符,则默认是public 2.属性必须指定访问修饰符 ☞方法之间可以互相调用.但是需要使用 $this引用 function test11(){ $this->test12(); } protected function test12(){ echo “test12 hello”; } 举例说明: class Person{ public $name; protected $age; private $salary; function __construct($name,$age,$salary){ $this->name=$name; $this->age=$age; $this->salary=$salary; } //成员方法 function showInfo(){ //这里说明在本类中可以使用 public protected 和private 修饰的变量.echo $this->name.“||”.$this->age.“||”.$this->salary; } } //创建一个人 $p1=new Person(“孙悟空”,30,1000); echo $p1->name;//可以 echo $p1->age;//报错 echo $p1->salary;//报错.?我们现在就想去访问protected 变量或者 private 变量, 通常的做法是提供 public 函数去访问这些变量.形式是 public function setXxx($val){ } public function getXxx(){ } public function showInfo(){ } public protected private 可以修饰属性和方法 (1)查看薪水(private)//获取这个人的薪水 public function getSalary($user,$pass){ if($user==“shunping” && $pass=“123”){ return $this->salary; }else{ return “sorry,你无法看”; } }(2)修改人的年龄 提供了两个函数.//修改年龄,对输入的值,进行校验.public function setAge($age){ if($age>1 && $age<120){ $this->age=$age; }else { echo “年龄范围不对”; } } //查看年龄 public function getAge(){ return $this->age; } 还有一种形式, 通过一对 __set 和 __get方法来操作我们的变量,不推荐.class A{ private $n1; private $n2; private $n3; //使用__set 方法来管理所有的属性 public function __set($pro_name,$pro_val){ $this->pro_name=$pro_val; } //使用__get 可以获取所有的属性值 public function __get($pro_name){ if(isset($pro_name)){ return $this->pro_name; }else{ return null; } } } $a1=new A(); $a1->n1=“hello”; echo $a1->n1; $a1->n2=890; echo “||”.$a1->n2; 可以直接写一个方法了操作变量 class Peron{ protected n1; private $n2; function showInfo($n1){ $this->n1=$n1; echo $this->n1.”||”$this->n2;} } 为什么需要继承 //应用场景开发一套学生管理系统(Pupil, Graduate ,...) //小学生类 class Pupil{ public $name; protected $age; protected $grade; public function showInfo(){ echo $this->name.“||”.$this->age; } public function tesing(){ echo “ 小学生考试..”; } } //研究生类 class Graduate{ public $name; protected $age; protected $grade; public function showInfo(){ echo $this->name.“||”.$this->age; } public function tesing(){ echo “研究生考试..”; } } 从上面的代码我们看出,代码的复用性不高,同时也会让管理代码成本增高. 解决之道(继承); 现在我们使用继承对上面的代码,进行改写.代码: //应用场景开发一套学生管理系统(Pupil, Graduate ,...) //父类 class Stu{ public $name; protected $age; protected $grade; public function showInfo(){ echo $this->name; } } //子类 class Pupil extends Stu{ public function testing(){ echo “ 小学生考试..”; } } class Graduate extends Stu{ public function testing(){ echo “研究生考试..”; } } //创建学生 $stu1=new Pupil(); $stu1->name=“小明”; $stu1->testing(); $stu1->showInfo(); //创建一个研究生 $stu2=new Graduate(); $stu2->name=“老明”; $stu2->testing(); $stu2->showInfo(); ☞从上面的代码我们可以看出: 所谓继承就是一个子类通过 extends 父类 把父类的(public / protected)属性和(public / protected)方法继承下来.继承的基本语法是: class 类名 extends 父类名{ //在写自己需要的属性和方法.} 讨论继承细节: 讨论继承细节: 1.父类的 public、protected 的属性和方法被继承.private 的属性和方法没有被继承.2.一个类只能继承一个父类,(直接继承).如果你希望继承多个类的属性和方法,则使用多层继承 class A{ public $n1=90;} class B extends A{ public $n2=“hello”;} class C extends B{ } $c=new C();echo $c->n1; 3.当创建子类对象的时候,默认情况下,不会自动调用父类的构造方法.class A{ public $n1=90; //构造方法 public function __construct(){ echo “A __construct”; } } class B extends A{ function __construct(){ echo “B __construct”; } } //创建B对象实例 $b=new B(); 4.如果我们希望去调用父类的构造方法,或者其它的方法(public / protected),可以这样处理(了解) 4.1 类名::方法名()4.2 parent::方法名()举例 class A{ public $n1=90; //构造方法 public function __construct(){ echo “A __construct”; } } class B extends A{ function __construct(){ echo “B __construct”; //显式的调用父类的方法 //A::__construct(); parent::__construct(); } } //创建B对象实例 $b=new B(); 5.当一个子类的方法和父类的方法完全一样(public protected), 我们称为方法的覆盖(方法重写) 重载 基本概念: 函数名一样,通过函数的参数个数或者是参数类型不同,达到调用同一个函数名,但是可以区分不同的函数 class A{ public function test1(){ echo “test1”;} public function test1($a){ echo “test1 hello”;} } 重载 $a =new A();$a->test1();$a->test1(456);上面的这用用法是不对.PHP5 中如何通过魔术函数来实现方法重载的效果 代码说明 class A{ public function test1($p){ echo “接收一个参数”; echo “ var_dump($p); } public function test2($p){ echo “接收两个参数 var_dump($p); } //这些提供一个__call //__call 是它一个对象调用某个方法,而该方法不存在,则 //系统会自动调用__call function __call($method,$p){ var_dump($p); if($method==“test”){ if(count($p)==1){ $this->test1($p); }else if(count($p)==2){ $this->test2($p); } } } } $a=new A(); $a->test(1); $a->test(56,90); ?> 小结: 关于重载 ① php5 默认情况下不直接支持方法重载 ② php5 可以同__call魔术方法,模拟一个方法效果的效果 方法的重写/方法的覆盖(override)① 先看一个问题 当一个父类知道所有的子类都有一个方法,但是父类不能确定该方法究竟如何写,可以让子类去覆盖这个方法,具体用法如下: //抽象一个Animal类 class Animal{ public $name; protected $price; function cry(){ echo “不知道动物怎么叫..”; } } class Dog extends Animal{ //覆盖 function cry(){ echo “小狗汪汪叫..”; } } class Pig extends Animal{ //覆盖.function cry(){ echo “哼哼叫..”; } } //创建一个只狗 $dog1=new Dog(); $dog1->cry(); $pig1=new Pig(); $pig1->cry();?> 关于方法重写细节讨论 1.要实现重写,要求子类的那个方法的名字和参数列表个数一摸一样,但是并不要求参数的名称一样.2.如果子类要去调用父类的某个方法(public / protected)则可以使用 parent::方法名(参数..), 父类名::方法名(参数...)3.在实现方法覆盖的时候,访问修饰符可以不一样 //但是必须满足: 子类的访问范围>=父类的访问范围 多态体现在什么地方? class Animal{ public function cry(){ echo '动物叫唤..'; } } class Cat extends Animal{ public function cry(){ echo “abc”; } } $cat1=new Cat(); $cat1->cry();当子类没有覆盖父类的方法则 $cat1->cry()调用的是父类,当子类覆盖了父类的方法,则调用自己的cry() 抽象类 为什么设计抽象类这个技术? 1.在实际开发中,我们可能有这样一种类,是其它类的父类,但是它本身并不需要实例化,主要用途是用于让子类来继承,这样可以到达代码复用.同时利于项目设计者,设计类.快速入门 //在实现方法覆盖的时候,访问修饰符可以不一样 //但是必须满足: 子类的访问范围>=父类的访问范围 abstract class Animal{ public $name; protected $age; //这个方法没有方法体,这个方法主要是为了让子类去实现.abstract public function cry(); } class Cat extends Animal{ public function cry(){ echo “猫猫叫唤..”; } } //创建一个子类实例 $cat1=new Cat(); $cat1->cry();使用抽象类的注意事项: 1.基本用法 abstract class 类名{ //方法 //属性 } 2.如果一个类使用abstract 来修饰,则该类就是抽象类, 如果一个方法被abstract修饰,则该方法就是抽象方法【抽象方法就不能有方法体.】 3.抽象类可以没有抽象方法.同时还可以有实现了的方法. //在实现方法覆盖的时候,访问修饰符可以不一样 //但是必须满足: 子类的访问范围>=父类的访问范围 abstract class Animal{ public $name=“abc”; protected $age; //这个方法没有方法体,这个方法主要是为了让子类去实现.abstract public function cry(); public function getName(){ return $this->name; } } class Cat extends Animal{ public function cry(){ echo “猫猫叫唤..”; } } //创建一个子类实例 $cat1=new Cat(); $cat1->cry(); echo $cat1->getName(); ?> 4.如果一个类中,只要有抽象方法,则该类必须声明为abstract abstract class A{ abstract function test(); } echo “ok”; 5.如果A类继承了一个抽象类 B,则要求A类实现从B类继承的所有抽象方法 案例: //这是一个抽象类 abstract class A{ abstract function test(); } //B类要么自己抽象,或者实现从A类继承的抽象方法.class B extends A{ function test(){ echo “我实现A:test()”; } } echo “hello” 接口 快速入门: //使用程序模拟现实情况 //定义规范(方法/属性) interfaceiUsb{ public function start(); public function stop(); } //编写相机类,让它去实现接口 //1.当一个类实现了某个接口,则要求该类必须实现这个接口的所有方法 class Camera implements iUsb{ public function start(){ echo “相机开始工作”; } public function stop(){ echo “相机停止工作...”; } } //编写手机类 class Phone implements iUsb{ public function start(){ echo “手机开始工作”; } public function stop(){ echo “手机停止工作...”; } } //如何使用 $camera1=new Camera(); $camera1->start(); $camera1->stop(); echo “ //手机对象 $phone1=new Phone(); $phone1->start(); $phone1->stop();?> 1.接口的使用基本语法 interface 接口名{ //属性 //方法 } 接口的方法都不能有方法体 如何去实现接口 class 类名 implements 接口名1,接口2.{ } 接口它的作用就是声明一些方法,供其它类来实现.接口还体现编程中我们希望的效果高内聚低耦合的特点: 继承是实现接口的关系一览图 深入讨论接口-interface 什么情况下可以考虑使用接口 1.定规范 2.定下规范,让别的程序员来实现,比如: //韩是项目经理 //学生管理系统(students) //定义接口 interfaceStuManageInterface{ public function addStudent($stu); public function delStudent($id); public function updStudent($stu); } //给三 classStuManage { public function tianjiaxuesheng(){ } } //四 3.当多个类,他们之间是平级的关系.这些类都会去实现某个功能,只是实现的方式不一样.接口的细节 1.不能去实例化一个接口 interfaceiUsb{ } $a=new iUsb();(错误!!) 2.接口中的所有方法,都不能有方法体 3.一个类可以去实现多个接口 语法: class 类名 implements 接口1,接口2{ } 4.接口中可以有属性,但是必须是常量,并且是public interfaceiUsb{ const A=90; } echo “ok”.iUsb::A; 5.接口的方法是public 【默认就是public 】 ,不能是 protected 和private 举例: interfaceiUsb{ const A=90; function test(); } echo “ok”.iUsb::A;6.类和接口之间关系一览图 代码: interface iUsb2{ public function a(); } interface iUsb3{ public function b(); } interfaceiUsb extends iUsb2,iUsb3{ const A=90; function test(); } class Class1 implements iUsb{ public function a(){ } public function b(){ } public function test(){ } } echo “ok”.iUsb::A;?> 从上面我们看出 ① 一个接口可以继承多个其它的接口.当一个类去实现了某些接口,则必须把所有接口的方法,都实现 继承和实现接口的比较:(1)可以认为实现接口是对单一继承的补充.(2)可以在不破坏类层级关系的前提下,对某个类功能扩展.final关键字 1.如果我们希望某个类不被其它的类来继承(可能因为安全考虑...), 可以使用final final class A{ } class B extends A{ } echo “ok”;?> 2.如果我们希望某个方法,比如计算个人所得税的方法,不能子类改写,可以使用fianl来修饰方法 class A{ final public function getRate($salary){ return $salary*0.08; } } class B extends A{ //不能去覆盖父类的getRate方法./*public function getRate($sal){ return $sal*0.01; }*/ } $b=new B(); echo $b->getRate(100);3.final关键字不能去修饰属性.const关键字的讲解 //当你有一个属性,不希望被修改,则考虑使用const做成常量 基本用法是 class A{ const常量名=赋初值;} interface 接口名{ const常量名=赋初值;} 常量是public 使用类名::常量名;接口名::常量 class A{ //常量在定义的时候,必须给初值.//const关键字前面不要带修饰符号.const TAX_RATE=0.08; public function payTax($val){ //常量不能修改.//A::TAX_RATE=0.01; //return $val*self::TAX_RATE;【ok】 return $val*A::TAX_RATE;//【ok】 } } $a=new A(); echo $a->payTax(200);?> 1.常量在定义的时候需要赋初值 2.常量不能修改.3.常量名不能有 $, 一般是大写, 默认是public 4.常量在类的内部使用 self::常量的名称类名::常量的名称 在类的外部使用类名::常量的名称.面向对象编程的综合案例 现在我们一起来完成一个稍微综合的案例---php版本的计算器,从而加深对php的认识,为下一步学习做准备。先用两个页面来完该计算器: myCal.php(界面)myResult.php(计算)知识点: 1.如何接收php页面提交的数据,并处理 2.php中如何使用javascript完成对数据合法性的校验 我们一起来开发.5.画出程序框架图: 6.编写代码: 现在我们分析如果要求把 xml 的作业改成面向对象的方式.怎么该? 做网站 Web程序。 需要制作一台可以在网络上被别人访问到的机器。 安装了浏览器的计算机: browser端 能够提供网络资源的计算机:(网站在这台计算机上),能够提供某种服务。Server端。 B/S是什么意思? 浏览器/服务器的架构: 请求:浏览器端向服务器端发送数据。Request 响应:服务器向浏览器端发送数据。回应,Response 什么样的计算机叫做服务器端? 安装了服务器软件的计算机。 Web服务器软件:iis,nginx,apache。 其中apache还是目前与php配合使用最多的服务器软件: 安装apache这个软件,使jsj成为一台web服务器。 http:// Apache的默认的文档目录 apache的安装目录下/htdocs/ 什么是静态网站,动态网站? 静态,网站上所有的内容,都是由静态页面提供的。 动态:网站的内容,是来源于某个数据源(数据库,互联网),而,在需要展示某些数据时,通过某种语言,将数据从数据源内提取,然后再展示到页面上。 如果需要做动态网站,需要 1,数据源(数据库)mysql数据库 2,某种语言(用于提取和展示数据之用)PHP Amp开发: 利用apache作为web服务器,使别人可以访问到我们的网站 利用mysql作为数据源,可以保存动态网站所需要的数据 利用php来获得某个操作所需要的数据。 小测试: 输出1-100 编写php文件: 访问这个php文件: 发现,可以访问到,但是不能解析。 Apache只有提供被访问的功能,而不能提供解析php代码的功能。 因此需要安装php程序,提供解析php代码的功能: 安装PHP: 所有的请求都是web服务器来接收的(apache),但是其中某些资源需要php来处理。通常的处理方式,是将php作为apache内部的一个模块来管理的。 将php安装成apache模块: 使用一个apache的指令,loadModule来完成: 解压php的安装包: 不需要安装可以直接执行 将php软件复制到相应的目录: E:/amp/php 由于不需要安装,目录内的可执行文件直接可以使用: 在php目录内,有个文件,就是php为apache提供的apache模块: 需要使用apache的LoadModule载入这个模块即可: 需要在apache的配置文件内,使用上面的LoadModule指令: apache的配置文件在 apache的安装目录/Conf/httpd.conf 增加如下指令即可: 修改配置文件后,需要重启动apache服务才可以: 配置apache,告知apache,哪样的前请求需要调用php来解析,而哪些不需要: 通过请求的资源的后缀名 使用apache的FilesMatch指令来完成: 当匹配到php后缀时,调用php来处理: Apache的配置文件内: 请求php文件时,php代码可以执行: 大家可以使用phpinfo()函数来测试以下,当前的php运行的环境: 安装php后,需要配置一些最基本的配置项: 修改php的配置文件: Php的安装目录/php.ini 根据需要,将相应的更改成php.ini即可: 由于php作为apache一个模块,因此需要告知apache,在哪里才能找到php的配置文件。利用apache的指令PhpIniDir来完成: 修改配置文件,达到某些目的: 1,时区 2, php扩展文件的目录。Php的很多功能,并不是内置到php的软件内的。在需要使用某个功能时,再载入即可。这个扩展的功能文件是被保存到某个目录内的,称之为php的扩展目录: Extension_dir: 修改完了php的配置,也需要重启apache才能生效 如果我们的php需要操作数据的话,需要利用数据软件了。安装Mysql。 1,安装 2,配置 配置mysql的安装目录,和mysql数据的保存目录: 安装完成时,勾选运行配置向导,完成配置的过程: 配置字符集: 简单介绍Mysql: 数据库服务器: 属于server端。因此,需要等待某个程序请求他才可以运行。 能够对mysql数据库服务器发出请求的我们称之为mysql客户端。 C/S Client客户端 Server服务器 在安装完mysql后,其实安装了2个软件1,mysql的服务器端,2,mysql的客户端。 我们需要使用php来操作mysql。 其实 在php操作mysql的过程中,php就变成了 mysql的客户端。 Php能够作为mysql的客户端,使用php的php_mysql.dll这个扩展完成,而且,这个扩展不是默认开启的。 开启相应的mysql的操作扩展,利用php的指令extension来完成。Php.ini: B/S C/S 1,服务器在监听(运行),提供某个服务 2,浏览器或者客户端,对服务器发出请求。在发送请求时,请求的数据一定要按照某种数据格式才可以。数据格式在网络数据传输时称之为网络协议。3,服务器接收到请求后,会根据请求数据,进行相应的操作。4,将处理好的结果返回给浏览器(客户端),回应。Response 5,浏览器端(客户端)对回应的数据进行展示输出,b/s 都是用浏览器发出请求的。 http https c/s架构,都是采用某个服务专用的客户端发出的请求。 Bs架构通常,任何两次请求回应周期是没有任何联系的。在发出请求时,都需要先建连接。 Cs通常,在连接一次之后,通常就会保持住这个连接,后续的操作,就不需要再次建立连接了。 PHP与apache联系: 1,php作为apache的模块而存在。loadModule 2,web服务器与php之间通过 CGI方式产生联系。CGI(通用网关接口),IIS+PHP。现在CGI被fastCGI。Nginx+PHP apache的虚拟主机: 通常一个web服务器,代理的是一个网站。 有时我们需要利用一个web服务器,管理多个站点。不同的站点拥有独立的域名。 通过配置apache服务器,达到,访问 Test.kang.com时,看到的是test目录的内容。Shop.kang.com时,看到的是shop目录的内容 Apache的基于域名的虚拟主机技术: 主机:一个网站,就是一些php文件的集合,一个保存php文件的目录 域名:指向某个网站的名称。 通过修改apache配置文件达到效果: Apache/comf/httpd.conf 原则上在这个配置文件内写虚拟主机的配置就可以了。但是通常我们都是将虚拟主机的配置写到某个单独的配置文件内,然后将这个虚拟主机配置文件再载入到apache的这个httpd.conf配置文件内。引入的操作: 虚拟主机的专门的配置文件: 编辑这个虚拟主机文件,增加虚拟主机: 在配置文件内,每一个 域名和目录是一个虚拟虚拟主机最基本的必备元素。 完成以上的操作,apache配置已经完成,apache上已经存在两个虚拟主机了: 在配置了虚拟主机之后,我们对web服务器的默认访问(没有使用配置的虚拟主机域名的访问),都会访问到默认的主机上。 默认的主机: 1,在配置了虚拟主机后:默认的主机就是 第一个配置的虚拟主机 2,在没有配置虚拟主机时,是htdocs目录。 那么怎么才能在使用虚拟主机的前提下,让localhost访问到原来的htdocs? 如何能够通过在浏览器上输入相应的虚拟主机域名访问到我们的虚拟主机呢? 在浏览器端,需要通过相应的域名,解析成目标服务器的ip地址才可以。 可以通过过浏览器端操作系统上自带的 域名解析文件完成。Hosts 配置虚拟主机时,常用的配置: 目录的权限的配置 利用apache的directory指令段完成配置 看 httpd.conf的配置: 目录级别的配置,对当前目录,及其后代目录有效果。 如果在apache的配置文件内,没有对某个目录进行配置,则采用默认的目录配置 可以通过修改默认的配置达到目的,但是通常是针对目录进行单独配置: 增加一个 Directory指令段: 为了将目录与虚拟主机联系起来,通常在VirtualHost内,使用Directory指令 Conf/extra/httpd-vhosts.conf 直接访问目录的配置: 在访问目录时,先检测当前目录是否配置了目录索引页,如果配置了索引页,则展示索引页的内容。目录的索引页使用apache的指令 directoryIndex完成配置。这个指令是可以写到directory段内。 如果没有配置目录索引页:则需要将目录的的内容以列表的形式显示出来,但是是通过配置apache的指令options加以配置,是否可以显示目录的索引列表。 可以在配置 options时 增加上允许符号连接的配置: Apache的配置文件系统: Apache程序,只会在apache服务器启动时,读取apache配置文件的内容,称之为apache主配置文件。 一旦配置文件的语法出错,就会导致apache服务器启动失败,提示: Apache提供一个apache的配置文件检查的功能: 也可以通过 cmd,命令行运行: Apache还有一个配置文件,称之为apache的分布式配置文件,apache允许在某个目录内部,使用独立的配置文件,来配置当前目录及其后代目录的中的一些设置。但是此时配置文件名称,就不是httpd.conf了 而是.htaccess 在这个.htaccess配置文件中配置的内容,只能是目录级别的配置。 但是默认情况下,分布式配置文件是不可以使用的。可以通过在主配置文件中使用apache的 Allowoverride指令加以配置。由于分布式配置文件是配置目录的,因此 allowoverride也是需要写到Directory段。 分布式与主配置文件的区别: 1,主配置文件需要保存到Conf目录中,而分布式需要保存到所有需要配置的目录中 2,主配置文件只要在apache启动时,才读取,而分布式配置文件,在apache访问到某个目录时都会读取一次。 作业 1,每个人配置一个虚拟主机: 域名是 test.ip.com Test.100.com 2,在test.ip.com上增加一个表单页面 Welcome.html页面 最好在表单提交时,验证姓名不能为空,为空给出提示,不能提交。 分析上面的例子: 发生了几次请求和回应的过程。
”;
有”.$global_nums;?>
有这”.Child::$nums;
接收到参数是”;
”;
”;第二篇:传智播客 PHP程序员笔记第一天