赵工的个人空间


专业技术部分转网页计算转业余爱好部分


 编程语言

常用的编程语言
C#编程语言基础
C#面向对象与多线程
C#数据及文件操作
JavaScript基础
JavaScript的数据类型和变量
JavaScript的运算符和表达式
JavaScript的基本流程控制
JavaScript的函数
JavaScript对象编程
JavaScript内置对象和方法
JavaScript的浏览器对象和方法
JavaScript访问HTML DOM对象
JavaScript事件驱动编程
JavaScript与CSS样式表
Ajax与PHP
ECMAScript6的新特性
Vue.js前端开发
PHP的常量与变量
PHP的数据类型与转换
PHP的运算符和优先规则
PHP程序的流程控制语句
PHP的数组操作及函数
PHP的字符串处理与函数
PHP自定义函数
PHP的常用系统函数
PHP的图像处理函数
PHP类编程
PHP的DataTime类
PHP处理XML和JSON
PHP的正则表达式
PHP文件和目录处理
PHP表单处理
PHP处理Cookie和Session
PHP文件上传和下载
PHP加密技术
PHP的Socket编程
PHP国际化编码
MySQL数据库基础
MySQL数据库函数
MySQL数据库账户管理
MySQL数据库基本操作
MySQL数据查询
MySQL存储过程和存储函数
MySQL事务处理和触发器
PHP操作MySQL数据库
数据库抽象层PDO
Smarty模板
ThinkPHP框架
Python语言基础
Python语言结构与控制
Python的函数和模块
Python的复合数据类型
Python面向对象编程
Python的文件操作
Python的异常处理
Python的绘图模块
Python的NumPy模块
Python的SciPy模块
Python的SymPy模块
Python的数据处理
Python操作数据库
Python网络编程
Python图像处理
Python机器学习
TensorFlow深度学习
Tensorflow常用函数
TensorFlow用于卷积网络
生成对抗网络GAN


首页 > 专业技术 > 编程语言 > PHP类编程
PHP类编程

PHP程序既可以选择面向过程的设计也可以选择面向对象的设计。面向对象的开发涉及类、对象、对象的属性、对象的方法等概念。

1.面向对象编程:

面向对象的编程就是将要处理的问题抽象为对象,然后通过对象的属性和行为来解决实际的问题。其中基本的概念是类和对象,特征是在程序设计中采用封装、继承、多态等设计方法。

1)封装性:

封装(Encapsulation)是指把对象的属性和行为结合成一个独立的单位,并尽可能隐蔽对象的内部细节。
通常来说,封装有两个含义:一是把对象的全部属性和行为结合在一起,形成一个不可分割的独立单位,对象的属性(除了公有的属性)只能由这个对象的行为来读取和修改;而是尽可能隐蔽对象的内部细节,对外形成一道屏障,与外部的联系只能通过外部接口实现。
封装机制将对象的使用者与设计者分开,使用者不必知道对象行为实现的细节,只需要用设计者提供的外部接口让对象去做。封装隐藏了复杂性,并提供了代码的重用性,从而降低了软件开发难度。

2)继承性:

继承(Inheritance),是一种连接类与类的层次模型。继承性是指特殊类的对象拥有其一般类的属性和行为,特殊类中不必重新定义已在一般类中定义过的属性和行为,而可以自动地、隐含地拥有其一般类的属性与行为。当这个特殊类又被它更下层的特殊类继承时,它继承来的和自己定义的属性和行为又被下一层的特殊类继承下去,继承是传递的。
继承性实现了软件模块的可重用性、独立性,因为要修改或增加某一属性或行为,只需在相应的类中进行改动,而它派生的所有类都自动地、隐含地作了相应的改动。

3)多态性:

多态性(Polymorphism)是指类中同一函数名对应多个具有相似功能的不同函数,可以使用相同的调用方式来调用这些具有不同功能的同名函数。

2.类:

类(Class),是具有相同行为和特点的多个对象的集合,是面向对象编程的核心和基础。面向对象中,将实体的属性和行为组合到一起形成类的定义。

1)定义类:

PHP中定义类的语法格式为:
class class_name {
  //这里是类的定义,包括属性和行为等
}
其中,class_name表示要创建的类名称,一般首字母应大写。大括号内是类的具体定义,可以在其中编写类的属性和方法等成员。
在类定义中使用关键字var声明变量即创建了类的属性,在类定义中声明函数即创建了类的方法。在PHP5中,属性和方法都可以分别加上public、protected、private等权限修饰符,代表可被访问的权限限制。示例:
<?php
class Product{
  //这里是类的定义,包括属性和方法等
public $id;
public $name;
public $price;
function toString()
{
  echo "编号:$this->id, 名称:$this->name, 价格:$this->price";
}
}
?>

2)实例化类:

类是具有某项功能的抽象模型,实际使用时需要对类实例化,对象就是类实例化后的实体。在PHP中定义好类后,便可以使用new关键字实例化一个类的对象。语法格式为:
$object_name=new class_name();
其中,$object_name表示要创建的对象名称,class_name是类的名称,跟在类名后面的括号是必须的。示例:
$car=new Product();
$bus=new Product();
当对象创建完成后,就可以直接调用类的方法和字段。一个类可以有多个对象。
PHP中,对象操作其属性与方法的引用操作符是“->”,$this是一个代表当前对象的引用。
PHP还可以使用“::”操作符来使用类的属性和方法,而且是没有为类声明任何实例的情况下引用,一般引用的是类的static属性和方法,或者常量。

3)构造函数:

大多数类都有称为构造函数的特殊方法,当示例化一个对象时自动调用构造函数,通常执行初始化,比如对成员进行初始化,或者执行一些特殊操作。PHP中构造函数的名称被统一命名为__construct()(前面是双下划线)。
如果在类中声明一个命名为__construct()的函数,那么该函数将被当成是一个构造函数,并且在建立对象实例时被执行。PHP中每个类最多只允许有一个构造函数。
创建构造函数的语法格式为:
function __construct([arg1, arg2, ..., argn]){
    //构造函数体
}
构造函数可以有参数或者默认值。示例:
<?php
class Product{
private $id;
private $name;
private $price;
function __construct($id, $name, $price)
{
  $this->id-$id;
  $this->name=$name;
  $this->price=$price;
}
function toString()
{
  echo "编号:$this->id, 名称:$this->name, 价格:$this->price \n";
}
}
?>
上述代码中,Product类包含了3个私有成员,不能在外部访问,所以需要创建一个构造函数来进行初始化,然后调用toString()函数进行输出。测试代码为:
$water=new Producr("W1-101", "纯净水", 3.5);
$water->toString();
$cup=new Product("H5-64", "夜光杯", 9.8);
$cup->toString();
旧版本的构造函数使用与类名相同的方法,有些类为了向下兼容,也使用与类名相同的方法做构造函数。

4)析构函数:

析构函数也有一个统一的命名,__destruct()(前面是双下划线)。析构函数允许在使用一个对象之后执行任意代码来清除内存,仅仅释放对象属性所占用的内存并删除对象相关的资源。析构函数不接受任何参数。示例:
<?php
class Counter{
private static $count=0;
function __construct() //构造函数
{
  self::$count++; //实例化时自动执行
}
function __destruct() //析构函数
{
  self::$count--; //释放时自动执行
}
function getCount() //创建一个方法
{
  return self::$count;
}
}
$num1=new Counter();
echo $num1->getCount().'<br />";
$num2=new Counter();
echo $num2->getCount()."<br />";
$num2=null;
echo $num1->getCount();
?>

3.类的成员:

PHP中的类成员主要可以分为:常量、属性和方法。

1)常量:

在PHP的类中使用const关键字定义常量,常量名称一般都大写,常量名称前面不需要$修饰符。语法格式为:
const NAME="VALUE";
这里,NAME表示常量的名称,VALUE表示常量的值,必须是一个常量表达式。
类常量的访问方式与普通变量不同,在类中访问常量要使用“self::常量名”语法,在外部访问类中的常量则使用“类名::常量名”语法。示例:
<?php
class Circle
{
const PI=3.1415926;
public function Area($r)
{
  return self::PI*$r*$r;
}
}
$s=new Circle();
echo "PI的值为:".Circle::PI."\n"; //访问Circle类中的常量PI
echo "所求圆面积是:".$s->Area(10);
?>
上述代码中,Circle类中使用self::PI来使用常量PI,而在类外部必须使用Circle::PI来使用常量PI。

2)属性:

属性用来表示实体的某一种状态,实际上就是类定义中的变量。通常都是在类的开始位置声明属性,并为其赋初值。在PHP中,属性也可以不声明而直接创建并赋值,但不推荐这样使用。示例:
<?php
class Student{
public $name;
var $sex=true;
public $age=22;
var $height;
var $weight;
}
?>
要引用类中的一个属性要使用“->”操作符。属性只属于某一个对象,所以还要指明该属性是属于哪个对象。使用属性的完整语法格式为:
$object_name->field; //$object_name是对象实例名称,field是要引用属性的名称
上述Student类的使用实例:
$xia=new Student();
$sex=$xia->sex?"女":"男";
echo "年龄:$xia->age";

3)方法:

在PHP中,类的方法(Method)就是在类中定义的函数,这些函数是用来定义类的行为。类中的方法都必须使用一些关键字进行定义。语法格式为:
scope function method_name() {
    //方法体
}
其中,scope表示方法的作用域范围,可选值有public、protected和private,如果没有设置,默认为public。method_name表示方法的名称,大括号中表示该方法的执行语句。
创建一个方法后,就可以通过“对象名->方法名()”格式调用类的公共方法。私有方法不能直接调用。

4.作用域关键字:

PHP可以通过对类的成员设置作用域来对访问权限进行限制,使数据分离,增强安全性。PHP中的作用域关键字有6个,分别是:abstract、final、private、protected、public和static。

1)Public关键字:

public关键字修饰的属性或者方法表示它是公共的,即在PHP的任何位置都可以通过对象名来访问该属性和方法。public是属性和方法的默认修饰符。

2)Private关键字:

private表示私有,通过private关键字修饰的属性和方法只能在类的内部使用,不能通过类的实例化对象调用,也不能通过类的子类调用。如果某些方法是作为另外一些方法的辅助,可以将该方法声明为私有。在PHP中,访问private修饰的成员时必须使用$this关键字。

3)Protected关键字:

protected表示受保护的,只能在类本身和子类中使用。使用protected关键字修饰字段和方法具有保护作用,通常用来帮助类或子类完成内部计算。如果试图从类外部调用protected的成员,将会出现致命性错误。

4)Final关键字:

final是PHP5新增的作用域关键字,可以用在类的前面或者方法的前面。当在一个方法的前面加上final关键字,表示该方法不可以被重写,即在该类的子类中只允许调用,不允许重新设置该方法的功能。如果一个类声明了final,那么该类不能被继承。这在不想让他人重新定义你的private方法时很重要。

5)Static关键字:

static关键字用来声明静态成员。静态的含义就是不用实例化出对象,直接用类名就可以访问。示例:
<?php
class settings {
static $login='ilia', $passwd='123456';
}
echo settings::$login;
?>
使用静态成员用::符访问,而不能使用->访问,否则会出错。
静态成员包括静态方法和静态属性。由于静态方法可以调用非对象示例,所以$this关键字不可以在声明为静态的方法中使用。一个类的静态成员会被该类所有的实例化对象共享,任何一个实例化对象对静态成员的修改都会映射到静态成员中,可以把静态成员看作一个全局变量。
静态成员与实例化对象无关,只与类有关,用来实现类要封装的功能和数据,但不包括特定对象的功能和数据。类的静态属性非常类似于函数的全局变量。静态方法类似于全局函数。静态方法可以完全访问类的属性,也可以由对象的实例来访问。
类常量类似静态成员,但定义后就不能修改。示例:
<?php
class scc {
const value='abc123';
function print_constant() {
   echo self::value; //在内部访问静态属性
}
}
echo scc::value; //在外部访问静态属性
?>

6)Abstract关键字

PHP5支持抽象类和抽象方法。任何一个类,如果它里面至少有一个方法被声明为抽象的,那么这个类就必须被声明为抽象的。因为抽象方法只有方法声明,而没有方法的实现,所以抽象类不能直接被实例化,必须先继承该抽象类,实现了所以抽象的方法,然后再实例化子类。
继承一个抽象类的时候,子类必须实现抽象类中的所有抽象方法,这些方法的可见性必须和抽象中一样。如果抽象类中某个抽象方法被声明为protected,那么子类中实现的方法就应当声明为protected或者public,而不能定义为private。抽象方法的语法格式为:
abstract function methon_name();
使用abstract声明一个类Example,那么该类中的方法都是抽象方法。示例:
<?php
abstract class AbstractClass
{
abstract function method1();
abstract function method2();
abstract function method();
}
?>
抽象类不能够实例化,它的作用类似于接口,就是产生子类的同时给子类一些特定的属性和方法。

5.类的继承:

继承是一个非常重要的面向对象特性,对于功能的设计和抽象非常有用,如果要对类似的对象增加新功能而无需重新编写公用的功能。通常将继承类称为派生类或子类,被继承类称为基类或父类。

1)继承类:

在PHP中,类继承通过使用extends关键字实现,并且类继承必须是单向继承,即一个类只能有一个基类(父类),但是一个类可以被多个子类继承。继承的语法格式为:
class childclass extends parentclass //childclass类继承parentclass类
{
  //类成员
}
子类不但可以拥有父类的成员,如方法和属性,还可以拥有自己本身新增的方法,但是子类不能拥有父类的私有成员。示例:
class Phone extends Machine {
  var $model="";
}
子类可以通过用同样的名字重新声明并覆盖父类的属性和方法,除非父类定义中使用了final关键字。覆盖后,仍然可以通过parent::来访问被覆盖的方法。

2)继承构造函数:

子类可以从基类中继承所有公共成员,当然也包括构造函数。在子类中运用基类中的构造函数与运用其他成员的不同之处在于子类可以显示调用基类中的构造函数,也可以隐式调用基类中的构造函数。
如果父类中有构造函数,并且子类中没有构造函数,那么子类在实例化时自动执行父类构造函数。
一个类可以调用另外一个类的构造函数,即使这两个类不是基类与子类关系也可以。非继承关系调用构造函数称为显式调用。如果一个子类继承了一个父类,子类只需要使用关键字parent就可以直接调用父类构造函数,称为隐式调用。

6.接口类:

接口类通过interface关键字来声明,接口中声明的方法必须是抽象方法,不能声明变量,只能使用const关键字声明为常量的成员属性,并且接口中的所有成员都必须具备public访问权限。语法:
interface intf_name {
   //常量成员;
   //抽象方法;
}
接口类不能实例化操作,需要通过子类来实现。但接口可以直接使用接口名称在接口外获取常量成员的值。
示例:
interface One {
   const CONSTANT='CONSTANT value';
   public function FunOne();
}
接口之间可以继承,使用extends关键字:
interface Two extands One {
   public function FunTwo();
}
因为接口类不能实例化,要使用接口中的成员就必须借助子类。在子类中继承接口需要使用implements关键字。如果要实现多个接口的继承,那么每个接口之间必须使用逗号连接。
<?php
interface Person {
function setName($name);
function getName();
}
interface Popedom {
function setPopedom($Popedom);
function getPopedome();
}
class Member implements Person,Popedom {
   private $name;
   private $popedom;
   function setName($name){
      $this->name=$name;
   }
   function getName(){
      echo "姓名:".$this->name;
   }
   function setPopedome($popedome){
      $this->popedome=$popedome;
   }
   function getPopedome(){
      echo "<br />权限:".$this->popedome;
   }
}
$pop=new Member();
$pop->setName("dwenzhao");
$pop->getName();
$pop->setPopedome("管理员");
$pop->getPopedome();
?>

ArrayAccess是PHP自带的一个接口,可以通过一个数组接口访问对象的数据,其中有4个方法:
·offsetExists($key):测试值是否存在。
·offsetGet($key):找回值。
·offsetSet($key,$value):赋值给$key。
·offsetUnset($key):移除指定值。

7.常用操作:

1)InstanceOf:

InstanceOf操作用来检查一个对象是否基于一个特定的类。示例:
class foo{};
$a=new foo;
if ($a InstanceOf foo) {
   useFoo($a);
}

2)clone:

使用clone可以创建多个有相同的语法结构的不同的类。示例:
class A{public $foo;};
$a=new A;
$a_copy=clone $a;
$a_another=clone($a);
在基类创建一个__clone()方法,这个方法可以在这个类执行克隆操作时执行。示例:
class A{
   public $is_copy=false;
   public function __clone() {
         this->is_copy=true;
   }
}
$a= new A;
$b=clone $a;
var_dump($a->is_copy, $b->is_copy);
__clone()方法可以对克隆后的副本对象重新初始化,不需要任何参数,其中自动包含$this和$that两个对象引用,$this是副本对象的引用,$that是原对象的引用。

3)比较对象:

当使用比较操作符“==”来比较对象时,如果两个对象拥有相同的属性和值,并且都是同一个类的实例,那么这两个类将认为是相等的。示例:
class A{public $foo=1;};
$a=new A; $b=new A; $c=new A;
$c->foo=2; $d=new StadClass;
echo (int) ($a==$b); //1
echo (int) ($a==$c); //0
echo (int) ($a==$d); //0
使用比较符“===”来比较两个对象时,两个对象只有在同为一个对象的引用时才相等。示例:
class A{public $foo=1;};
$a=new A; $b=new A; $c=clone $b; $d=$a;
echo (int) ($a===$b); //0
echo (int) ($a===$c); //0
echo (int) ($a===$d); //1

4)魔术方法:

PHP中有很多以双下划线开头的方法,称为魔术方法,包括前面介绍的__construct()、__destruct()和__clone()。
①__set()方法和__get()方法:
__set()方法和__get()方法用于对私有成员进行赋值及获取值的操作。
__set()方法包含两个参数,分别表示变量名称和变量值,没有返回值,用于在程序运行过程中为私有成员属性设置值。这个方法不需要主动调用,可以在方法前加上private关键字防止用户直接调用。
boolean __set([String property_name,][mixed value_to_assign])
__get()方法有一个私有成员属性名参数,返回一个允许对象在外面使用的值,用于在对象的外部获取私有成员属性的值。这个方法同样不需要主动调用,可以在方法前加private关键字防止用户直接调用。
boolean __get([String property_name])
示例:
<?php
class Rectangle{
private $Width;
public $Height;
function __set($property_name, $value){
      echo “自动调用__set()方法为属性$property_name赋值\n”;
  $this->$property_name=$value;
}
function __get($property_name){
      echo “自动调用__get()方法获取属性$property_name的值\n”;
  return isset($this->$property_name)?$property_name:null;
}
}
$rect=new Rectangle();
$rect->Width=23;
$rect->Height=40; //直接为私有属性赋值,此时会自动调用__set()方法进行赋值
//直接获取私有属性的值,此时会自动调用__get()方法,返回属性的值
echo “矩形的高为:”.$rect->Height.”,宽为:”.$rect->Width;
?>
②_isset()方法和__unset()方法:
如果对象中存在_isset()方法,当在类的外部使用isset()函数检测对象中的私有成员属性时,就会自动调用_isset()方法完成对私有成员属性的检测操作。语法为:
bool __isset(string name)
__unset()方法帮助unset()函数在类的外部删除指定的私有成员属性。语法为:
void __unset(string name)
③__call()方法:
__call()方法的作用时,当程序试图调用不存在或不可见的成员方法时,PHP会先调用__call()方法来存储方法名及其参数。__call()方法包含两个参数,即方法名和方法参数,其中方法参数是以数组形式存在的。示例:
<?php
class math{
function __call($name, $arg){
  if (count($arg)>2) return false;
  switch ($name) {
     case 'add':
         return $arg[0]+$arg[1]; break;
     case 'sub':
         return $arg[0]-$arg[1]; break;
     case 'div':
         return $arg[0]*$arg[1]; break;
  }
}
}
④__autoload方法:
如果要在一个页面中引入很多的类,就需要使用include_once()或require_once()将类一个一个地引入。在PHP5中,__autoload()函数可以自动实例化需要使用的类。当程序要用到一个类,但该类还没有被实例化时,__toString()方法在指定的路径下自动查找和该类名称相同的文件。如果找到则继续执行,否则报告错误。示例:
<?php
function __autoload($class_name) {
   require_once "/php/classes/{$class_name}.inc.php";
}
$a=new Class1;
?>
⑤__toString()方法:
作用是当使用echo或print输出对象时,将对象转化为字符串。示例:
<?php
class sample {
   public $foo=1;
   function __construct() {
      $this->foo=rand();
   }
   function __toString() {
      return (string)$this->foo;
   }
}
echo new sample();
?>
如果没有__toString()方法,直接输出对象时将会发生致命错误。输出对象时,echo或print语句后面直接跟要输出的对象,中间不要加多余的字符,否则__toString()方法不会执行。
⑥__sleep()和__wakeup():
序列化是把PHP变量转化为一串编码后字符串,这个字符串可以被用来重新创建变量,适用于复杂的PHP类型。例如,数组和对象不能简单地写入一个文件或者存入数据库。序列化过程由serialize()来完成,反序列化过程由unserialize()来完成。
class test {
   public $foo=1, $bar, $baz;
   function __construct() {
      $this->bar=$this->foo*10;
      $this->baz=($this->bar+3)/2;
   }
}
$a=serialize(new test()); //对示例类进行编码
$b=unserialize($a)); //恢复类,并赋值给$b
对象经过编码类似为:O:4:"test":3:{s:3:"foo";s:3:"bar";i:10;s:3:"baz";d:6.5;}
__sleep()方法用来指定实例被序列化时执行的动作。示例:
class test {
   public $foo=1, $bar, $baz;
   function __construct() {
      $this->bar=$this->foo*10;
      $this->baz=($this->bar+3)/2;
   }
   function __sleep() {return array('foo');}
}
这样序列化后的数据列好控制,结果为:O:4:"test":1:{s:3:"foo";i:1;}
__wakeup()方法,如果在反序列化时使用,目的是创建在序列化时被忽略掉的属性。
class test {
   public $foo=1, $bar, $baz;
   function __construct() {
      $this->bar=$this->foo*10;
      $this->baz=($this->bar+3)/2;
   }
   function __wakeup() {self:: __construct();}
}

5)对象遍历:

一般情况下,PHP只允许使用foreach()来遍历可见的属性,key对应对象的属性名,value对应于属性值。
PHP5允许对象执行一个iterator的接口来指定对象的遍历过程。要使用这个功能,对象必须实现rewind、current、key、next和valid方法。
class file1 Implements Iterator {
   private $fp,$line=NULL, $pos=0;
   function __construct($path) {
      $this->fp=fopen($path,"r");
   }
   public function rewind() {
      rewind($this->fp);
   }
   public function current() {
      if ($this->line===NULL) {
         $this->line=fgets($this->fp);
      }
      return $this->line;
   }
   public function key) {
      if ($this->line===NULL) {
         $this->line=fgets($this->fp);
      }
      if ($this->line===FALSE) return FALSE;
      return $this->pos;
   }
   public function next() {
      $this->line=fgets($this->fp);
      ++$this->pos;
      return $this->line;
   }
   public function valid() {
      return ($this->line!==FALSE);
   }
}
<?php
function __autoload($class_name) {
   require "./{$class_name}.php";
}
foreach (new file1(__FILE__) as $k=>$v) {
   echo "{$k} {$v}";
}
?>

Copyright@dwenzhao.cn All Rights Reserved   备案号:粤ICP备15026949号
联系邮箱:dwenzhao@163.com  QQ:1608288659