PHP基础学习

导论

开发历史

发布版本 发布日期
1.0 1995年6月8日
5.0 2004年7月13日
7.0 2015年12月3日
8.0 2020年11月26日

注释

作用:对重点进行标注;方便了解代码等

// 单行注释

/* 多行注释 */

基础语法

变量

程序使用数值可变化的量,与常量相反

变量的声明特点

  1. 必须以$符号开始
  2. 首字母不能以数字开始
  3. 名字区分大小写
  4. 不能用特殊符号(中文,下划线_不算特殊符号)
  5. 变量的命名要有意义

常量

常量值被定义后,在其它任何地方不可被改变。一般用大写字母表示。

使用define()函数设置常量,函数语法如下:

define(string $constant_name, mixed $value, bool $case_insensitive = false): bool

参数解释如下:

  • constant_name:常量名称
  • value:常量的值
  • case_insensitive:常量名是否区分大小写,默认是区分的(新版本传入true,会产生警告)

变量作用域

变量作用域是指脚本中变量可被使用的部分。

共有四种不同的变量作用域:

  • local
  • global
  • static
  • parameter

局部和全局作用域

在所有函数外部定义的变量,拥有全局作用域。如果要在一个函数内部访问一个全局变量,则需要使用global关键字。

$x = 10;
function test()
{
    // 使用global关键字访问 全局变量x
    global $x;
    $y = 15;
    echo $y;
    echo $x;
}

test();

static作用域

当一个函数完成时,它内部所有变量通常都会被删除。如果希望某个局部变量不被删除,则需要在声明变量时使用static关键字。

function getNum()
{
    static $x = 10;
    echo $x;
    $x++; // 使用static关键字后,多次调用,变量x会增加;否则始终为10
}

getNum();
getNum();
getNum();

参数作用域

参数是通过调用代码将值传递给函数的局部变量。

function getNum($x)
{
    echo $x; // 5
}
getNum(5);

echo和print语句

动态输出HTML内容

echo、print和print_r的区别如下:

  • echo 可以输出一个或多个字符串
  • print 只能输出简单类型的值,如int、string等
  • print_r 可以输出复杂类型的值,如数组、对象

echo输出的速度比print块;echo是PHP语句,没有返回值,printprint_r是函数,函数有返回值。print的返回值为1(整型),print_r的返回值是true(布尔型)。

超级全局变量

在一个脚本的全部作用域都可使用的内置变量。

名称 作用
$GLOBALS 包含了全部变量的全局组合数组
$_SERVER 包含了诸如头信息header、路径path、以及脚本位置等信息的数组
$_REQUEST 收集HTML表单提交的数据
$_POST 用于收集post方式提交的表单数据
$_GET 用于收集get方式提交的表单数据
$_FILES 包含客户端上传文件的所有信息
$_ENV 包含服务端环境变量的数组
$_COOKIE 包含cookie信息
$_SESSION 包含session信息

$_SERVER变量中的重要元素:

元素/代码 描述
$_SERVER['SERVER_ADDR'] 当前运行脚本所在的服务器的 IP 地址。
$_SERVER['SERVER_NAME'] 当前运行脚本所在的服务器的主机名。如果脚本运行于虚拟主机中,该名称是由那个虚拟主机所设置的值决定。(如: www.w3cschool.cn)
$_SERVER['SERVER_SOFTWARE'] 服务器标识字符串,在响应请求时的头信息中给出。 (如:Apache/2.2.24)
$_SERVER['SERVER_PROTOCOL'] 请求页面时通信协议的名称和版本。例如,"HTTP/1.0"。
$_SERVER['REQUEST_METHOD'] 访问页面使用的请求方法;例如,"GET", "HEAD","POST","PUT"。
$_SERVER['REQUEST_TIME'] 请求开始时的时间戳。从 PHP 5.1.0 起可用。 (如:1377687496)
$_SERVER['HTTP_ACCEPT'] 当前请求头中 Accept: 项的内容,如果存在的话。
$_SERVER['HTTP_ACCEPT_CHARSET'] 当前请求头中 Accept-Charset: 项的内容,如果存在的话。例如:"iso-8859-1,*,utf-8"。
$_SERVER['HTTP_HOST'] 当前请求头中 Host: 项的内容,如果存在的话。
$_SERVER['REMOTE_ADDR'] 浏览当前页面的用户的 IP 地址。
$_SERVER['REMOTE_HOST'] 浏览当前页面的用户的主机名。DNS 反向解析不依赖于用户的 REMOTE_ADDR。

魔术常量

有8个魔术常量的值随着它们在代码中的位置变化而变化

名称 作用
__LINE__ 在当前文件中的行数
__FILE__ 文件的完整路径和文件名。如果用在被包含文件中,则返回被包含的文件名。
__DIR__ 文件所在的目录。如果用在被包含文件中,则返回被包含文件所在的目录。
__FUNCTION__ 返回该函数被定义时的名称(区分大小写)
__CLASS__ 返回该类被定义时的名称(区分大小写)
__TRAIT__ trait的名字
__METHOD__ 返回该方法被定义时的名称(区分大小写)
__NAMESPACE__ 当前命名空间的名称(区分大小写)

数据类型

整型

数学中的整数,用int表示

字符串

声明字符串的三种方式

  • 用单引号声明
  • 用双引号声明
  • 用字界符声明(用于输入大段字符)

单引号和双引号声明字符串的区别

  1. 双引号解析变量,单引号不解析变量(双引号中插入变量时,建议使用{}隔开,否则无法解析)
  2. 双引号解析转义字符,单引号不解析转义字符
  3. 单引号效率高于双引号,尽量使用单引号

浮点型

可看作数学中的小数,用float表示

布尔型

判断真假,true表示真,false表示假

数组

复合数据类型,用array表示

对象

必须使用class关键字进行声明

资源

一些可见或不可见的文件、网络和数据(如图片、数据库和网络等),用resource表示

NULL

空值,使用null表示,代表没有

三种可产生null类型的情况如下:

  1. 直接给变量赋值为null
  2. 直接输出一个没有给任何值的变量
  3. 使用unset()函数将变量销毁

相关重要函数

函数名 参数 作用 返回值
empty() 一个变量 检测是否为空 变量值为false或者为null,返回true,否则返回false
isset() 一个或多个变量 检测是否存在 只要有一个变量为null,返回false,否则返回true
unset() 一个变量 毁掉变量 返回null

运算符

流程控制

if语句

if...else语句

if...else if...else语句

switch语句

循环语句

while

只要指定的条件成立,则循环执行代码块

do...while

首先执行一次代码块,然后在指定的条件成立时重复这个循环

for

循环执行代码块指定的次数

foreach

根据数组中每个元素来循环代码块

函数 *

实现某种功能,使用function表示。通过调用函数来执行。主要包含参数、作用和返回值

// 声明函数
function say() {
    // 要执行的代码
}

// 调用函数
say();

函数准则

  • 函数的名称应该提示出它的功能
  • 函数名称以字母或下划线开头(不能以数字开头)

函数相关词语

  • 形参:声明函数时括号内的变量,可进行预设
  • 实参:调用函数时括号内的变量
  • 返回值:使用return语句给函数返回值
// 形参:$x,$y
function getNum($x, $y = 10)
{
    echo $x; // 5
    echo $y; // 10

    // 返回值 return语句
    return $x + $y;
}

// 实参 5
getNum(5);

命名空间 *

介绍

从广义上来说,命名空间是一种封装事物的方法。

命名空间可解决的问题如下:

  1. 避免用户编写的代码与PHP内部的类/函数/常量或第三方类/函数/常量的名称冲突。
  2. 为很长的标识符名称(通常是为了解决第一个问题而定义的)创建一个别名,提高源代码的可读性。

定义命名空间

默认情况下,所有常量、类和函数名都放在全局空间下。

命名空间使用关键字namespace来声明。如果一个文件包含命名空间,它必须在其它所有代码之前进行声明

<?php
// 定义代码在 'MyProject' 命名空间中
namespace MyProject;

// ...代码...

在声明命名空间之前唯一合法的代码是定义源文件编码方式的 declare 语句。

<?php
declare(endcoding = 'UTF-8')

// 定义代码在 'MyProject' 命名空间中
namespace MyProject;

// ...代码...

子命名空间

与目录文件的关系类似,命名空间也允许指定层次化的命名空间的名称。

<?php
namespace MyProjcet\Sub; // 声明分层次的单个命名空间

// 当前定义的常量、函数和累,都在 MyProjcet/Sub 空间下
const STATUS = 1;
function say() {}
class person() {
}

命名空间的使用 **

命名空间的引用主要有以下三种:

  1. 非限定名称,或不包含前缀的类名称。
  2. 限定名称,或包含前缀的名称。
  3. 完全限定名称,或包含了全局前缀操作符的名称。

实例如下:

file1.php

<?php
namespace Foo\Bar\subnamespace;

const FOO = 1;
function foo() {
    echo __NAMESPACE__;
}

class foo {
    static function staticmethod(){
        echo __NAMESPACE__;
    }
}

file2.php

<?php
namespace Foo\Bar;
include 'file1.php';

const FOO = 2;
function foo() {
    echo __NAMESPACE__;
}

class foo {
    static function staticmethod(){
        echo __NAMESPACE__;
    }
}

/* 非限定名称 */
foo(); // Foo\Bar\foo
foo::staticmethod(); // Foo\Bar\foo
echo FOO; // Foo\Bar\foo => 2

/* 限定名称 */
subnamespace\foo(); // Foo\Bar\subnamespace\foo
subnamespace\foo::staticmethod(); // Foo\Bar\subnamespace\foo
echo subnamespace\FOO; // Foo\Bar\subnamespace\foo => 1

/* 完全限定名称-使用反斜杠 */
\Foo\Bar\foo(); // 解析为函数 Foo\Bar\foo
\Foo\Bar\foo::staticmethod(); // 解析为类 Foo\Bar\foo, 以及类的方法 staticmethod
echo \Foo\Bar\FOO; // 解析为常量 Foo\Bar\FOO

使用命名空间:别名/导入

两种使用别名:为类名称或为命名空间使用别名。但PHP不支持导入函数和常量。

使用use操作符导入/使用别名

<?php
namespace foo;
use My\Full\Classname as Another;

// 下面的例子与 use My\Full\NSname as NSname 相同
use My\Full\NSname;

面向对象 **

在面向对象的程序设计(英语:Object-oriented programming,缩写:OOP)中,对象是一个由信息及对信息进行处理的描述所组成的整体,是对现实世界的抽象。

面向对象内容

  • 类:定义了一件事物的抽象特点。类的定义包含了数据的形式以及对数据的操作。
  • 对象:是类的实例。
  • 成员变量:定义在类内部的变量。该变量的值对外是不可见的,但是可以通过成员函数访问。在类被实例化为对象后,该变量即可成为对象的属性。
  • 成员函数:定义在类的内部,可用于访问对象的数据。
  • 继承:继承性是子类自动共享父类数据结构和方法的机制,这是类之间的一种关系。在定义和实现一个类时,可以在一个已经存在的类的基础上来进行,把这个已经存在的类所定义的内容作为自己的内容,并加入若干新的内容。
  • 父类:一个类被其他类继承,可将该类称为父类,或基类,或超类。
  • 子类:一个类继承其他类称为子类,也可称为派生类。
  • 多态:多态性是指相同的操作或函数、过程可作用于多种类型的对象上并获得不同的结果。不同的对象,收到同一消息可以产生不同的结果,这种现象称为多态性。
  • 重载:简单说,就是函数或者方法有同样的名称,但是参数列表不相同的情形,这样的同名不同参数的函数或者方法之间,互相称之为重载函数或其他方法。
  • 抽象性:是指将具有一致的数据结构(属性)和行为(操作)的对象抽象成类。一个类就是这样一种抽象,它反映了与应用有关的重要性质,而忽略其他一些无关内容。任何类的划分都是主观的,但必须与具体的行为有关。
  • 封装:是指将现实世界中存在的某个客体的属性与行为绑定在一起,并放置在一个逻辑单元内。
  • 构造函数:主要用来在创建对象时初始化对象,即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中。
  • 析构函数:析构函数destructor与构造函数相反,当对象结束其生命周期时(例如对象所在的函数已调用完毕),系统自动执行析构函数。

类的定义

定义类的通常语法格式如下:

<?php 
class phpClass {  
    var $var1;
    var $var2 = "constant string";   
    function myfunc ($arg1, $arg2) {}
} 
?>

解析如下:

  • 类使用class关键字后加上类名定义;
  • 类名后的一对大括号{}内可以定义变量和方法;
  • 类的变量使用var来声明,变量也可以初始化值;
  • 函数定义类似PHP函数的定义,但函数只能通过该类及其实例化对象访问。

实例如下:

class Site
{
    /* 成员变量 */
    var $url;
    var $title;

    /* 成员函数 */
    function setUrl($url)
    {
        $this->url = $url;
    }

    function getUrl()
    {
        echo $this->url . PHP_EOL;
    }

    function setTitle($title)
    {
        $this->title = $title;
    }

    function getTitle()
    {
        echo $this->title . PHP_EOL;
    }
}

变量$this代表自身的对象;PHP_EOL为换行符。

创建对象

类创建后,可以使用new运算符来实例化该类的对象:

$baidu = new Site();
$taobao = new Site();
$tengxun = new Site();

在实例化对象后,我们可以使用该对象调用成员方法,该对象的成员方法只能操作该对象的成员变量。

$baidu->setTitle('百度');
$taobao->setTitle('淘宝');
$tengxun->setTitle('腾讯');

$baidu->setUrl('https://baidu.com');
$taobao->setUrl('https://taobao.com');
$tengxun->setUrl('https://qq.com');

$baidu->getTitle(); // 百度
$taobao->getTitle(); // 淘宝
$tengxun->getTitle(); // 腾讯

$baidu->getUrl(); // https://baidu.com
$taobao->getUrl(); // https://taobao.com
$tengxun->getUrl(); // https://qq.com

构造函数

用来在创建对象时初始化对象,即为对象成员变量赋初始化值,总与new运算符一起使用在创建对象的语句中。语法格式如下:

void __construct ([ mixed $args [, $... ]] )

上面的实例则可以写成

function __construct($par1, $par2)
{
    $this->url = $par1;
    $this->title = $par2;
}

因此,我们可以直接省略setTitle和setUrl方法了

class Site
{
    /* 成员变量 */
    var $url;
    var $title;

    /* 成员函数 */
    function __construct($par1, $par2)
    {
        $this->title = $par1;
        $this->url = $par2;
    }

    function getUrl()
    {
        echo $this->url . PHP_EOL;
    }

    function getTitle()
    {
        echo $this->title . PHP_EOL;
    }
}

$baidu = new Site('百度', 'https://baidu.com');
$taobao = new Site('淘宝', 'https://taobao.com');
$tengxun = new Site('腾讯', 'https://qq.com');

$baidu->getTitle(); // 百度
$taobao->getTitle(); // 淘宝
$tengxun->getTitle(); // 腾讯

$baidu->getUrl(); // https://baidu.com
$taobao->getUrl(); // https://taobao.com
$tengxun->getUrl(); // https://qq.com

析构函数

析构函数destructor与构造函数相反,当对象结束其生命周期时(例如对象所在的函数已调用完毕),系统自动执行析构函数。

void __destruct ( void )

实例

class MyName
{
    var $name;

    function __construct()
    {
        print '构造函数' . PHP_EOL;
        $this->name = 'MyName';
    }

    function __destruct()
    {
        // TODO: Implement __destruct() method.
        print '析构函数' . PHP_EOL . $this->name;;

    }
}

$obj = new MyName();
/**
 * 构造函数
 * 析构函数 MyName
 */

继承

使用关键字extends来继承一个类,PHP不支持多继承

class Child extends Site {
   // 代码部分
}

方法重写

如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖,也称为方法的重写。

访问控制

PHP对属性或方法的访问控制,是通过在前面添加关键字实现的。关键字有以下三种:

  • public(公有):公有的类成员可以在任何地方被访问,使用var定义也视为公有。
  • protected(受保护):受保护的类成员可以被其自身以及其子类和父类访问。
  • private(私有):私有的类成员则只能被其定义所在的类访问。

接口

使用接口interface,可以指定某个类必须实现哪些方法,但不需要定义这些方法的具体内容。

接口是通过interface关键字来定义的,就像定义一个标准的类一样,但其中定义所有的方法都是空的。接口的特性是,接口中定义的所有方法都必须是公有的

要实现一个接口,需要使用implements操作符。类中必须实现接口中定义的所有方法,否则会报一个致命错误。类可以实现多个接口,用逗号来分隔多个接口的名称。

// 接口
interface iTemplate
{
    public function setVariable($name, $var);
    public function getHtml($template);
}

// 实现接口
class Template implements iTemplate
{

    public function setVariable($name, $var)
    {
        // TODO: Implement setVariable() method.
    }

    public function getHtml($template)
    {
        // TODO: Implement getHtml() method.
    }
}

抽象类

任何一个类,如果它里面至少有一个方法被声明为抽象的,那么这个类就必须声明为抽象的。定义为抽象的类不能被实例化。

被定义为抽象的方法只是声明了其调用方式(参数),不能定义其具体的功能实现。

继承一个抽象类的时候,子类必须定义父类中的所有抽象方法;另外,这个方法的访问控制必须和父类中一样(或者更为宽松)。例如某个抽象方法被声明为受保护的,那么子类中实现的方法就应该声明为受保护的或者公有的,而不能声明为私有的。

static关键字

声明类属性或方法为static(静态),就可以不实例化类而直接访问。

静态属性不能通过一个类已实例化的对象来访问(但静态方法可以)。

由于静态方法不需要通过对象即可调用,所以伪变量$this在静态方法中不可用。

静态属性不可以由对象通过->操作符来访问。

class Foo
{
    public static $word = 'foo';

    public function getWord()
    {
        return self::$word;
    }

    static public function getStaticWord()
    {
        return self::$word;
    }
}

echo Foo::$word . PHP_EOL; // foo
$foo = new Foo();
echo $foo->getWord() . PHP_EOL; // foo
echo $foo->getStaticWord() . PHP_EOL; // foo
echo $foo::getStaticWord() . PHP_EOL; // foo

final关键字

如果父类中的方法被声明为final,则子类无法覆盖该方法。如果一个类被声明为final,则不能被继承。

以下代码会报错

class Base
{
    public function getName()
    {
        echo __FUNCTION__;
    }

    final public function getClass()
    {
        echo __CLASS__ . PHP_EOL;
    }
}

class Child extends Base
{
    public function getClass()
    {
        echo __CLASS__ . PHP_EOL;
    }
}

// Fatal error: Cannot override final method Base::getClass()

调用父类构造方法

PHP不会在子类的构造方法中自动的调用父类的构造方法。要执行父类的构造方法,需要在子类的构造方法中调用 parent::__construct()

class ParentName
{
    var $name;

    function __construct()
    {
        echo 'ParentName'.PHP_EOL;
    }
}

class Child extends ParentName
{
    function __construct()
    {
        parent::__construct(); // 会输出ParentName
        echo 'Child';
    }
}

参考文档

https://www.w3cschool.cn/php/php-tutorial.html

这些信息可能会帮助到你: 关于我们 | 饿了么返钱 | 捐赠支持

文章名称:PHP基础学习
文章链接:https://www.bysjb.cn/php.html
THE END
分享
二维码
打赏
< <上一篇
下一篇>>