预定义变量
- $_GET:获取所有表单以get方式提交的数据
- $_ POST:获取所有表单以post方式提交的数据
- $_REQUEST:get和post提交的都会保存
- $GLOBALS:PHP中所有的全局变量
- $_SERVER:服务器信息
- $_SESSION:session会话信息
- $_COOKIE:cookie会话信息
- $_ENV:环境信息
- $_FILES:用户上传的文件信息
命名空间
首先要知道什么是命名空间,命名空间就是一种封装事物的方法。举个花生:
一个文件a.txt文件,它可以存在于demo/demo01下,也可以存在于demo/demo02下,但是在同一目录、路径下不可能存在两个a.txt文件,如果在demo/demo01路径之外访问a.txt文件,则必须将路径写全,如:demo/demo01/a.txt。
PHP命名空间可以解决下面两个问题:
- 用户编写的代码与PHP内部的类/函数/常量或第三方类/函数/常量之间的名字冲突。
- 为很长的标识符名称(通常是为了缓解第一类问题而定义的)创建一个别名(或简短)的名称,提高源代码的可读性。
定义命名空间
命名空间通过关键字namespace来声明,如果想在一个文件中声明命名空间,那么它必须在其他所以代码之前进行声明命名空间。如:
<?php
// 定义代码在 'MyProject' 命名空间中
namespace MyProject;
// ... 代码 ...
如要命名多个不同的命名空间代码:
<?php
namespace MyProject {
const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }
}
namespace AnotherProject {
const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }
}
?>
以下代码会出现错误:
<html>
<?php
namespace MyProject; // 命名空间前出现了“<html>” 会出现错误 - 命名空间必须是程序脚本的第一条语句
?>
子命名空间
PHP命名空间也可以像文件目录那样,多层次的提现命名空间的名称。
<?php
namespace MyProject\Sub\Level; //声明分层次的单个命名空间
const CONNECT_OK = 1;
class Connection { /* ... */ }
function Connect() { /* ... */ }
?>
上面的例子创建了常量 MyProject\Sub\Level\CONNECT_OK,类 MyProject\Sub\Level\Connection 和函数 MyProject\Sub\Level\Connect。
命名空间使用
- 非限定名称,或不包含前缀的类名称,例如 $a=new foo(); 或 foo::staticmethod();。如果当前命名空间是 currentnamespace,foo 将被解析为 currentnamespace\foo。如果使用 foo
的代码是全局的,不包含在任何命名空间中的代码,则 foo 会被解析为foo。
警告:如果命名空间中的函数或常量未定义,则该非限定的函数名称或常量名称会被解析为全局函数名称或常量名称。- 限定名称,或包含前缀的名称,例如 $a = new subnamespace\foo(); 或 subnamespace\foo::staticmethod();。如果当前的命名空间是 currentnamespace,则 foo
会被解析为 currentnamespace\subnamespace\foo。如果使用 foo
的代码是全局的,不包含在任何命名空间中的代码,foo 会被解析为subnamespace\foo。- 完全限定名称,或包含了全局前缀操作符的名称,例如, $a = new \currentnamespace\foo(); 或 \currentnamespace\foo::staticmethod();。在这种情况下,foo
总是被解析为代码中的文字名(literal name)currentnamespace\foo。
PHP面向对象
对象的主要三个特性:
- 对象的行为:可以对 对象施加那些操作,开灯,关灯就是行为。
- 对象的形态:当施加那些方法是对象如何响应,颜色,尺寸,外型。
- 对象的表示:对象的表示就相当于身份证,具体区分在相同的行为与状态下有什么不同。
面向对象内容
PHP类定义:
<?php
class Site {
/* 成员变量 */
var $url;
var $title;
/* 成员函数 */
function setUrl($par){
$this->url = $par;
}
function getUrl(){
echo $this->url . PHP_EOL;
}
function setTitle($par){
$this->title = $par;
}
function getTitle(){
echo $this->title . PHP_EOL;
}
}
?>
类使用 class 关键字后加上类名定义。
类名后的一对大括号({})内可以定义变量和方法。
类的变量使用 var 来声明, 变量也可以初始化值。
函数定义类似 PHP 函数的定义,但函数只能通过该类及其实例化的对象访问。
PHP创建对象:
我们将使用new运算符来实例化该类的对象
<?php
class Site {
/* 成员变量 */
var $url;
var $title;
/* 成员函数 */
function setUrl($par){
$this->url = $par;
}
function getUrl(){
echo $this->url . PHP_EOL;
}
function setTitle($par){
$this->title = $par;
}
function getTitle(){
echo $this->title . PHP_EOL;
}
}
$taobao = new Site;
$google = new Site;
// 调用成员函数,设置标题和URL
$taobao->setTitle( "淘宝" );
$google->setTitle( "Google 搜索" );
$taobao->setUrl( 'www.taobao.com' );
$google->setUrl( 'www.google.com' );
// 调用成员函数,获取标题和URL
$taobao->getTitle();
$google->getTitle();
$taobao->getUrl();
$google->getUrl();
?>
结果为:
淘宝
Google 搜索
www.taobao.com
www.google.com
PHP构造函数:
构造函数主要用于创建对象时初始化对象,为对象成员变量赋初始值,在创建对象的语句中与new运算符一起使用。格式如下:
function __construct( $par1, $par2 ) {
$this->url = $par1;
$this->title = $par2;
}
析构函数:
析构函数(destructor) 与构造函数相反,当对象结束其生命周期时(例如对象所在的函数已调用完毕),系统自动执行析构函数。
PHP 5 引入了析构函数的概念,这类似于其它面向对象的语言,其语法格式如下:
也就是说,析构函数在脚本运行结束之前自动调用,在 PHP 中有一种垃圾回收机制,当对象不能被访问时就会自动启动垃圾回收机制,收回对象占用的内存空间。而析构函数正是在垃圾回收机制回收对象之前调用的。
<?php
class MyDestructableClass {
function __construct() {
print "构造函数\n";
$this->name = "MyDestructableClass";
}
function __destruct() {
print "销毁 " . $this->name . "\n";
}
}
$obj = new MyDestructableClass();
?>
输出结果:
构造函数
销毁 MyDestructableClass
继承:
PHP使用extends继承一个类,不支持多继承
<?php
// 子类扩展站点类别
class Child_Site extends Site {
var $category;
function setCate($par){
$this->category = $par;
}
function getCate(){
echo $this->category . PHP_EOL;
}
}
方法重写:
如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
访问控制:
PHP 对属性或方法的访问控制,是通过在前面添加关键字 public(公有),protected(受保护)或 private(私有)来实现的。
- public(公有):公有的类成员可以在任何地方被访问。
- protected(受保护):受保护的类成员则可以被其自身以及其子类和父类访问。
- private(私有):私有的类成员则只能被其定义所在的类访问。
属性的访问控制
类属性必须定义为公有,受保护,私有之一。如果用 var 定义,则被视为公有。
<?php
/**
* Define MyClass
*/
class MyClass
{
public $public = 'Public';
protected $protected = 'Protected';
private $private = 'Private';
function printHello()
{
echo $this->public;
echo $this->protected;
echo $this->private;
}
}
$obj = new MyClass();
echo $obj->public; // 这行能被正常执行
echo $obj->protected; // 这行会产生一个致命错误
echo $obj->private; // 这行也会产生一个致命错误
$obj->printHello(); // 输出 Public、Protected 和 Private
/**
* Define MyClass2
*/
class MyClass2 extends MyClass
{
// 可以对 public 和 protected 进行重定义,但 private 而不能
protected $protected = 'Protected2';
function printHello()
{
echo $this->public;
echo $this->protected;
echo $this->private;
}
}
$obj2 = new MyClass2();
echo $obj2->public; // 这行能被正常执行
echo $obj2->private; // 未定义 private
echo $obj2->protected; // 这行会产生一个致命错误
$obj2->printHello(); // 输出 Public、Protected2 和 Undefined
?>
方法的使用控制:
类中的方法可以被定义为公有,私有或受保护。如果没有设置这些关键字,则该方法默认为公有。
<?php
/**
* Define MyClass
*/
class MyClass
{
// 声明一个公有的构造函数
public function __construct() { }
// 声明一个公有的方法
public function MyPublic() { }
// 声明一个受保护的方法
protected function MyProtected() { }
// 声明一个私有的方法
private function MyPrivate() { }
// 此方法为公有
function Foo()
{
$this->MyPublic();
$this->MyProtected();
$this->MyPrivate();
}
}
$myclass = new MyClass;
$myclass->MyPublic(); // 这行能被正常执行
$myclass->MyProtected(); // 这行会产生一个致命错误
$myclass->MyPrivate(); // 这行会产生一个致命错误
$myclass->Foo(); // 公有,受保护,私有都可以执行
/**
* Define MyClass2
*/
class MyClass2 extends MyClass
{
// 此方法为公有
function Foo2()
{
$this->MyPublic();
$this->MyProtected();
$this->MyPrivate(); // 这行会产生一个致命错误
}
}
$myclass2 = new MyClass2;
$myclass2->MyPublic(); // 这行能被正常执行
$myclass2->Foo2(); // 公有的和受保护的都可执行,但私有的不行
class Bar
{
public function test() {
$this->testPrivate();
$this->testPublic();
}
public function testPublic() {
echo "Bar::testPublic\n";
}
private function testPrivate() {
echo "Bar::testPrivate\n";
}
}
class Foo extends Bar
{
public function testPublic() {
echo "Foo::testPublic\n";
}
private function testPrivate() {
echo "Foo::testPrivate\n";
}
}
$myFoo = new foo();
$myFoo->test(); // Bar::testPrivate
// Foo::testPublic
?>
接口:
接口是通过intaface关键字来定义的,就像定义一个标准的类一样,但其中定义的所有方法都是空的,
接口中定义的所有方法都必须得是公有,这是接口的特性。
要实现一个接口,使用 implements 操作符。类中必须实现接口中定义的所有方法,否则会报错误。类可以实现多个接口,用逗号来分隔多个接口的名称。