PHP学习笔记——入门篇
学习网站
因为要学Mysql,所以先学PHP,来记录一下自己的学习进度和容易遗忘的知识点。
下面是一些学习网站:
1.菜鸟驿站
https://www.runoob.com/php/php-tutorial.html
2.w3school:
https://www.w3school.com.cn/php/index.asp
3.PHP.net:
https://www.php.net/
1.echo&print
echo可以输出多个字符串,print只能输出一个字符串;
echo比print稍快,echo不返回任何值,print返回1.
1.1 echo
1.1.1 echo输出数组
<?php
//定义变量
$cars=array("Volvo","BMW","Toyota");
//{}表示求变量值
echo "The brand of my car is {$cars[1]}";
echo
?>
注意用echo的时候应该用"{$数组名[index]}"
输出:
The brand of my car is BMW
1.1.2 单双引号的问题
变量值:无引号输出变量值,单引号会原样输出引号内的内容(直接转化为字符串),双引号会替换变量值。双引号内的变量加不加{}都行。
,和.:echo使用单引号时用.进行拼接,双引号使用,进行拼接。
举个例子:
<?php
$name = 'Sabina';$city = 'JN';$age = 20;
echo "hello, my name is {'$name'}, i come from {$city}, i am {$age} years old";
/*hello, my name is {'Sabina'}, i come from JN, i am 20 years old*/
echo"<br>";
echo 'hello, my name is ' . $name . ', i come from ' . $city . ', i am ' . $age . ' years old';
/*hello, my name is Sabina, i come from JN, i am 20 years old*/
?>
参考博文:
php中echo单引号双引号及大括号的作用
php中的echo单引号_谈谈PHP中的单引号和双引号
1.2 print
1.2.1 字符串和变量
print()和print都可以用。
<?php
$txt1="Learn PHP";
$txt2="home";
$cars=array("Volvo","BMW","SAAB");
print $txt1;//Learn PHP
print "<br>";
print "Study PHP at $txt2";
//Study PHP at home
print "<br>";
print "My car is a {$cars[0]}";
//My car is a volvo
?>
2. 数据类型
PHP数据类型包括字符串、整数、浮点数、逻辑、数组、对象、NULL。
2.1 字符串
用单双引号都行。
2.2 整数
整数可以用十进制,十六进制(0x开头),八进制(0开头)。
var_dump($变量名)可以返回数据类型和值。
实例:
<?php
$x=33;
var_dump($x);//33
?>
2.3 NULL值
特殊的 NULL 值表示变量无值。NULL 是数据类型 NULL 唯一可能的值。
NULL 值标示变量是否为空。例如:
<?php
$x="Hello world!";
$x=null;
var_dump($x);//NULL
?>
2.4 对象
不太明白,占坑,一会再写
没写的没有疑问,有疑问的时候再补充。
2.5 数组
数组可以在一个变量中存储多个值。
2.5.1 数组的分类
- 数值数组-带有数字键的数组
- 关联数组-带有指定键的数组
- 多维数组-包含一个或多个数组的数组
2.5.2 数组的创建
2.5.2.1 数值数组的创建
$cars=array("Volvo","BMW","toyota");
或者:
$cars[0]="Volvo";
$cars[1]="BMW";
$cars[2]="Toyota";
2.5.2.2 关联数组的创建
$age=array("Peter"=>"35","Ben"=>"37","Joe"=>"43");
或者:
$age['Peter']="35";
$age['Ben']="37";
$age['Joe']="43";
2.5.3 数组的遍历
count(数组名)可以获得数组的长度。
2.5.3.1 遍历数值数组:
<?php
$cars=array("Volvo","BMW","Toyota");
$arrlength=count($cars);
for($x=0;$x<$arrlength;$x++)
{
echo $cars[$x];
echo "<br>";
}
?>
2.5.3.2 遍历关联数组:
一维关联数组的遍历:
<?php
$age=array("Peter"=>"35","Ben"=>"37","Joe"=>"43");
foreach($age as $x=>$x_value)
{
echo "Key=" . $x . ", Value=" . $x_value;
echo "<br>";
}
?>
输出:
Key=Peter, Value=35
Key=Ben, Value=37
Key=Joe, Value=43
二位数组的遍历:
<?php
$myArray=array(
"1"=>array("11"=>"val11","12"=>"val12","13"=>"val13"),
"2"=>array("21"=>"val21","22"=>"val22","23"=>"val23"),
"3"=>array("31"=>"val31","32"=>"val32","33"=>"val33")
);
print("<ul>");
foreach($myArray as $key=>$val) {
print("<li>".$key."</li>");
if (is_array($val)) { //判断$val的值是否是一个数组,如果是,则进入下层遍历
print("<ul>");
foreach($val as $key=>$val) {
print("<li>".$key."=>".$val."</li>");
}
print("</ul>");
}}
print("</ul>");
?>
< ul >和< li >是标签,作用是显示个实心小圆点和空心小圆点。
输出:
1
11=>val11
12=>val12
13=>val13
2
21=>val21
22=>val22
23=>val23
3
31=>val31
32=>val32
33=>val33
2.5.4 数组的排序
- sort() - 对数组进行升序排列
- rsort() - 对数组进行降序排列
- asort() - 根据关联数组的值,对数组进行升序排列
- ksort() - 根据关联数组的键,对数组进行升序排列
- arsort() - 根据关联数组的值,对数组进行降序排列
- krsort() - 根据关联数组的键,对数组进行降序排列
2.5.5 数组函数手册
格式:
var_dump($数组名);
输出:array(数组大小){[键值1]=> 数据类型(大小)“数据1”[键值2]=> 数据类型(大小)“数据2”[键值3]=> 数据类型(大小)“数据3”……}
举个例子:
<?php
$x=array("a"=>"apple","b"=>"banana");
var_dump($x);
//array(2){["a"]=>string(5)"apple"["b"]=>string(6)"banana"}
?>
3.字符串函数
3.1 统计字符串的长度——strlen()函数
<?php
echo strlen("hello world!")//12
?>
3.2 统计字符串的单词数——str_word_count()
echo str_word_count("Hello World!");//2
3.3 反转字符串strrev()
<?php
echo strrev("Hello world!");//!dlrow olleH
感觉不太实用啊。
3.4 检索文本 strpos()
检索指定文本,检索成功返回首个字符位置,失败返回FALSE。
<?php
echo strpos("Hello world!","world");//6
?>
3.5 替换文本str_replace()
作用是用一些字符串代替原来文本中的指定字符串。格式:
str_replace(“被替换文本”,“替换文本”,“包含被替换文本的原文本”)
<?php
echo str_replace("world","Kitty","Hello world!")//Hello Kitty!
?>
3.6 更多PHP string函数
https://www.w3school.com.cn/php/php_ref_string.asp
4.类型比较
注意:
“0” = = null: bool(false)
“0” === null: bool(false)
其他详见:
https://www.runoob.com/php/php-types-comparisons.html
5.常量
常量是全局的。
5.1 常量的设置——define()
用define()构建一个常量:
bool define(string $name)
- name:必选参数,常量名称。
- value:必选参数,常量值。
<?php
define("greeting","你好");
echo greeting;//你好
?>
6.运算符
6.1 算术运算符
±*/%
6.2 赋值运算符
用于向变量写值。包括:
+=、-=、*=、/=、%=
例如:x+=y相当于x=x+y
6.3 字符串运算符
不多bb,直接上例子:
<?php
//串接
$a="Hello";
$b=$a." world!";
echo $b;//Hello world!
//串接赋值
$x="Hello";
$x.=" world!";
echo $x;//Hello world!
?>
6.4 递增/递减运算符
包括前递增/递减(++/-- 变量,先递增/递减再返回),后递增/递减(变量++/- -,先返回再递增/递减)
6.5 比较运算符
包括:
!=,<>(不等于),!==(不全等于),>,>=,<,<=
6.6 逻辑运算符
与:and/&&
或:or/||
非:!
亦或(两变量有且只有一个为true时返回true):xor
6.7 数组运算符
用于对数组进行操作。包括:
6.7.1 +(联合)
两数组元素相加,键名相同值不同会覆盖(+前面的值会覆盖后面的值);键名不同,值相同不会覆盖)
举例:
<?php
//键名相同,值不同
$x = array("a" => "apple", "b" => "banana");
$y = array("a" => "orange", "d" => "peach");
$z = $x + $y;
var_dump($z);
/*输出:array(3) { ["a"]=> string(5) "apple" ["b"]=> string(6) "banana"
["d"]=> string(5) "peach" }*/
echo "<br>";
//键名不同,值相同
$x = array("a" => "apple", "b" => "banana");
$y = array("c" => "apple", "d" => "peach");
$z = $x + $y;
var_dump($z);
/*输出:array(4) { ["a"]=> string(5) "apple" ["b"]=> string(6) "banana"
["c"]=> string(5) "apple" ["d"]=> string(5) "peach" }*/
//键名,值都不同
echo "<br>";$x = array("a" => "apple", "b" => "banana");
$y = array("c" => "orange", "d" => "peach");
$z = $x + $y;
var_dump($z);
/*输出:array(4) { ["a"]=> string(5) "apple" ["b"]=> string(6) "banana"
["c"]=> string(6) "orange" ["d"]=> string(5) "peach" }*/
echo "<br>";
?>
6.7.2 = =和===(相等和恒等)、!=和!= =(不相等和不恒等)
当两数组拥有相同的键和值时,= =返回true,当顺序和类型也相同时,===也返回true.
不相等和不恒等返回值的真值和它们对应的值相反。举例:
<?php
$x = array("a" => "red", "b" => "green");
$y = array("b" => "green", "a" => "red");
var_dump($x == $y);//bool(true)
echo "<br>";
var_dump($x === $y);//bool(false)
echo "<br>";
var_dump($x != $y);//bool(false)
echo "<br>";
var_dump($x!== $y);//bool(true)
echo "<br>";
$x = array("a" => "red", "b" => "green");
$y = array("a" => "red", "b" => "green");
var_dump($x == $y);//bool(true)
echo "<br>";
var_dump($x === $y);//bool(true)
echo "<br>";
var_dump($x != $y);//bool(false)
echo "<br>";
var_dump($x !== $y);//bool(false)
echo "<br>";
?>
6.7.3 !=和<>(不相等)
两者等价。
6.8 三元运算符
6.8.1 语法格式
(1)(expr1)?(expr2):(expr3)
(2)(expr1)?:(expr3)
(3)(expr1)??(expr3)
如果expr1为true时(1)返回expr2,(2)(3)返回expr1;反之都返回expr3。
以下代码都返回m:
<?php
$test = 'm';
// 普通写法
$username = isset($test) ? $test : 'nobody';
echo $username, "<br>";
// PHP 5.3+ 版本写法
$username = $test ?: 'nobody';
echo $username, "<br>";
//PHP7.0+写法
$username=$test ?? 'nobody';
echo $username,"<br>";
?>
6.9 组合比较符(PHP7+)
<=>进行两个变量的比较,这两个变量可以是int,float,string.
$c=$a<=>$b;
//当$a>$b时返回1,$a=$b时返回0,$a<$b时返回-1
6.10 运算符优先级
https://www.runoob.com/php/php-operators.html
常见的:
&&>=>and
||>=>or
<?php
$a = 3;
$b = false;
$c = $a or $b;
var_dump($c);
// int(3)
$d = $a || $b;
var_dump($d);
//bool(true)
?>
7.条件语句
7.1 if语句
if (条件)
{
//条件成立时要执行的代码;
}
7.2 if…else语句
if (条件)
{
//条件成立时执行的代码;
}
else
{
//条件不成立时执行的代码;
}
7.3 if…elseif…else语句
if(条件)
{
// if 条件成立时执行的代码;
}
elseif (条件)
{
// elseif 条件成立时执行的代码;
}
else
{
//条件不成立时执行的代码;
}
7.4 Switch语句
<?php
switch(n){
case label1:
//当label1=n,执行代码1;
break;
case label2:
//当label2=n,执行代码2;
break;
case label3:
//当label3=n,执行代码3;
break;
...
default:
//如果n不等于任何一个label,执行此处代码
}
?>
8.循环语句
8.1 while循环
8.1.1 while
语法:
while(条件){
//statement
}
例如:
<?php
$i=1;
while($i<=5)
{
echo "The number is " . $i . "<br>";
$i++;
}
?>
输出:
The number is 1
The number is 2
The number is 3
The number is 4
The number is 5
8.1.2 do…while
语法:
do{
//statement
}
while(条件)
例如:
<?php
$i=1;
do
{
$i++;
echo "The number is " . $i . "<br>";
}
while ($i<=5);
?>
输出:
The number is 2
The number is 3
The number is 4
The number is 5
The number is 6
8.2 for循环
8.2.1 for循环
语法:
for(初始值;条件;增量){//初始值和增量参数可为空
//statement
}
8.2.2 foreach循环
foreach(array_name as $val){
statement;
}
array_name是当前数组名,每次循环中,array_name数组的当前元素被赋给$val.并且数组内下标下移一步。
2.
foreach(array_name as $key=>$val){
statement;
}
多了一个$ key,可以把当前元素的下标传给$key.
9.超级全局变量
这些超级全局变量在一个脚本的全部作用域都可用。
9.1 $GLOBALS
$GLOBALS是一个包含了全部变量的全局数组,变量的名字就是数组的键。
使用方法举例:
<?php
$x = 75;
$y = 25;
$z=NULL;
function addition()
{
$GLOBALS['z'] = $GLOBALS['x'] + $GLOBALS['y'];
}
addition();
echo $z;//100
?>
顺便说一下global()的使用:
<?php
$a = 11;
function fun()
{
global $a;//如果没有,变量$a不会被定义。
echo $a;
$a++;
}
fun();//输出11
echo '<br>'.$a;//输出12
?>
9.2 $_SERVER
是一个Web服务器创建的数组。
9.3 $_REQUEST
用于收集HTML表单中提交的数据。点击Submit按钮时,表单数据将发送至< form >标签中action属性中指定的脚本文件。
<html>
<body>
<form method="post" action="<?php echo $_SERVER['PHP_SELF'];?>">//表单
Name: <input type="text" name="fname">//输入字段
<input type="submit">//提交按钮
</form>
<?php
$name = $_REQUEST['fname'];
echo $name;
?>
</body>
</html>
9.4 $ _POST和$_GET
用法和$_REQUEST差不多。HTML标签中method属性分别是post和get。
<html>
<body>
<form method="post" action="<?php echo $_SERVER['PHP_SELF'];?>">
Name: <input type="text" name="fname">
<input type="submit">
</form>
<?php
$name = $_POST['fname'];
echo $name;
?>
</body>
</html>
$_GET也可以收集URL中发送的数据。
举个例子,下面是一个包含超链接的HTML页面:
<html >
<body>
<a href="test_get.php?subject=PHP&web=runoob.com">Test $GET</a>
//当用户点击Test $GET,参数subject&web会发送到下面的php文件
</body>
</html>
下面是test_get.php文件:
<?php
echo "Study ".$_GET['subject']."@".$_GET['web'];
//这个文件用$_GET来获取这些数据。
?>
10.PHP函数
10.1 函数的创建
<?php
funtion FunctionName(){}
?>
10.2 添加参数
语法:
funtion funtionName($varName){
//statement
}
例如:
<?php
function writeName($fname,$punctuation)
{echo $fname . " Refsnes" . $punctuation . "<br>";}
echo "My name is ";
writeName("Kai Jim",".");
echo "My sister's name is ";
writeName("Hege","!");
echo "My brother's name is ";
writeName("Ståle","?");
?>
输出:
My name is Kai Jim Refsnes.
My sister's name is Hege Refsnes!
My brother's name is Ståle Refsnes?
10.3 返回值
格式:
funtion funtionName($varName){
//statement
return $var;
}
11.PHP魔术常量
这些常量随着他们在代码的位置的改变而改变。
11.1 __LINE__
当前行号。
<?php
echo '这是第 " ' . __LINE__ . ' " 行';
?>
11.2 __FILE__
该文件的绝对路径。
11.3 __DIR__
当前文件所在的目录。
11.4 __FUNCTION__
函数名。
11.5 __CLASS__
类名。
<?php
class test {
function _print() {
echo '类名为:' . __CLASS__ . "<br>";
echo '函数名为:' . __FUNCTION__ ;
}
}
$t = new test();
$t->_p
输出:
类名为:test
函数名为:_print
11.6 __TRAIT__
用法见我的另一篇blog:
PHP trait的属性及使用方法
11.7 __METHOD__
返回函数名称。
11.8 __NAMESPACE__
当前命名空间的名称。
用法:
<?php
namespace MyProject;
echo '命名空间为:"', __NAMESPACE__, '"';
// 输出:命名空间为: "MyProject"
?>
12.PHP命名空间(namespace)
有点多,我认为不能放在入门篇里面,学的时候有点吃力,估计是因为用法不太熟练。所以梳理一下。
namespace是在PHP 5.3加入的。为了解决用户编写的代码和PHP内部的类和类成员或者第三方类和类成员的名字一样,这样就提高了代码的可读性。
其实创建命名空间和在文件夹里套娃,再根据文件路径寻找到想要的文件是一样的。
映射关系大概类似于:
namespace->file
class->一个可以包含function,const,var的file
const->project1
function->和类一样,可以包含function,const,var的file
访问全局的类或者成员在类名/成员名前面加个/就行了。
说的不太确切,但是概念是差不多的,可以用这个帮助理解namespace。
12.1 定义命名空间
可以定义多个。全局代码需要用一个不带名称的namespace语句加大括号括起来。
<?php
namespace MyProject {
const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }
}
namespace AnotherProject {
const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }
}
namespace { // 全局代码
session_start();
$a = MyProject\connect();
echo MyProject\Connection::start();
}
?>
注意事项:声明命名空间之前唯一合法的代码是用于定义源文件编码方式的declare语句。
<?php
declare(encoding='UTF-8');
namespace a{}
namespace b{}
...
?>
namespace前面也不能加< html >标签!
12.2 子命名空间
喜闻乐见的套娃阶段。可以对命名空间进行层次化的定义:
<?php
namespace A\B\C;
const OK=1;
class classname{}
function func(){}
?>
以上代码创建了常量A\B\C\OK,类A\B\C\classname,函数A\B\C\func().
12.3 命名空间的使用
下面是命名空间类名的使用和类中静态方法的调用的三种方式:
12.3.1 非限定名称
该类名称不包含前缀。
格式:
$a=new foo();//类名的使用
foo::staticmethod();//类中静态方法的调用
如果当前命名空间是currentnamespace,该类foo将会被解析为currentnamespace中的类名,即currentnamespace\foo.如果currentnamespace中foo未定义,则该函数或者常量名称会被解析为全局函数名称或者常量名称。
12.3.2 限定名称
该类名称包含前缀。
格式:
$a=new subnamespace\foo();//类的使用
subnamespace\foo::staticmethod();//类中静态方法的使用
如果当前命名空间为currentnamespace,foo会被解析为currentnamespace\subnamespace\foo.如果调用foo的代码是全局的,即在namespace中调用。foo会被解析为subnamespace\foo.
12.3.3 完全限定名称
该类名称包含全局前缀操作符。
格式:
$a=new \currentnamespace\foo();
\currentnamespace\foo::staticmethod();
12.3.* 一个实例
file1.php
<?php
namespace Foo\Bar\subnamespace;
const FOO = 1;
function foo() {}
class foo
{
static function staticmethod() {}
}
file2.php
<?php
namespace Foo\Bar;
include 'file1.php';
const FOO = 2;
function foo() {}
class foo
{
static function staticmethod() {}
}
/* 非限定名称 */
foo(); // 解析为函数 Foo\Bar\foo
foo::staticmethod(); // 解析为类 Foo\Bar\foo ,方法为 staticmethod
echo FOO; // 解析为常量 Foo\Bar\FOO
/* 限定名称 */
subnamespace\foo(); // 解析为函数 Foo\Bar\subnamespace\foo
subnamespace\foo::staticmethod(); // 解析为类 Foo\Bar\subnamespace\foo,
// 以及类的方法 staticmethod
echo subnamespace\FOO; // 解析为常量 Foo\Bar\subnamespace\FOO
/* 完全限定名称 */
\Foo\Bar\foo(); // 解析为函数 Foo\Bar\foo
\Foo\Bar\foo::staticmethod(); // 解析为类 Foo\Bar\foo, 以及类的方法 staticmethod
echo \Foo\Bar\FOO; // 解析为常量 Foo\Bar\FOO
?>
表示命名空间及其内部成员的图:
访问全局变量,函数或常量,都可以使用完全限定名称。例如 \strlen() 或 \Exception 或 \INI_ALL。
在命名空间内部访问全局类,函数和常量。
<?php
namespace Foo;
function strlen() {}
const INI_ALL = 3;
class Exception {}
$a = \strlen('hi'); // 调用全局函数strlen
$b = \INI_ALL; // 访问全局常量 INI_ALL
$c = new \Exception('error'); // 实例化全局类 Exception
?>
12.4 命名空间和动态语言特征
在命名空间中动态访问元素必须使用完全限定名称,所以\是不必要的.
下面的file1.定义了一个全局类、方法和常量。
动态访问时直接用名字就可以。
<?php
class classname
{
function __construct()
{
echo __METHOD__,"\n";
}
}
function funcname()
{
echo __FUNCTION__,"\n";
}
const constname = "global";
$a = 'classname';
$obj = new $a; // prints classname::__construct
$b = 'funcname';
$b(); // prints funcname
echo constant('constname'), "\n"; // prints global
?>
下面的file2 中定义了在namespacename中的类,方法和常量,并引入了file1.在namespacename中动态访问全局元素时则必须使用完全限定名称。直接用元素名访问的话会访问到全局元素。前面的反斜杠可接可不接。
<?php
namespace namespacename;
class classname
{
function __construct()
{
echo __METHOD__,"\n";
}
}
function funcname()
{
echo __FUNCTION__,"\n";
}
const constname = "namespaced";
include 'example1.php';
$a = 'classname';
$obj = new $a; // 输出 classname::__construct
$b = 'funcname';
$b(); // 输出函数名
echo constant('constname'), "\n"; // 输出 global
/* 如果使用双引号,使用方法为 "\\namespacename\\classname"*/
$a = '\namespacename\classname';
$obj = new $a; // 输出 namespacename\classname::__construct
$a = 'namespacename\classname';
$obj = new $a; // 输出 namespacename\classname::__construct
$b = 'namespacename\funcname';
$b(); // 输出 namespacename\funcname
$b = '\namespacename\funcname';
$b(); // 输出 namespacename\funcname
echo constant('\namespacename\constname'), "\n"; // 输出 namespaced
echo constant('namespacename\constname'), "\n"; // 输出 namespaced
?>
12.5 namespace关键字和__NAMESPACE__魔术常量
__NAMESPACE__魔术常量是一个包括当前命名空间的字符串。
<?php
namespace MyProject;
echo '"',\_\_NAMESPACE\_\_,'"';//"MyProject"
?>
namespace可以用来显式访问当前命名空间的元素,等价于类中的self操作符。
<?php
namespace MyProject;
use blah\blah as mine; // 引入了 blah\blah 命名空间,并定义了个别名mine
mine\mine(); // 调用函数 blah\blah\mine()
namespace\blah\mine(); // 调用函数 MyProject\blah\mine()
namespace\func(); // 调用函数 MyProject\func()
namespace\sub\func(); // 调用函数 MyProject\sub\func()
namespace\cname::method(); // 调用 MyProject\cname 类的静态方法
$a = new namespace\sub\cname(); // 实例化 MyProject\sub\cname 类的对象
$b = namespace\CONSTANT; // 将常量 MyProject\CONSTANT 的值赋给 $b
?>
namespcace操作符操作全局代码:
<?php
namespace\func(); // calls function func()
namespace\sub\func(); // calls function sub\func()
namespace\cname::method(); // calls static method "method" of class cname
$a = new namespace\sub\cname(); // instantiates object of class sub\cname
$b = namespace\CONSTANT; // assigns value of constant CONSTANT to $b
?>
12.6 use操作符实现别名/导入
PHP命名空间支持为类名称和命名空间使用别名。
导入的操作使用use来实现的。
1.使用use操作符导入、使用别名
<?php
namespace foo;
use My\Full\namespace as Another;
use My\Full\NSname;
//等价于use My\Full\NSname as NSname.
use \ArrayObject;//导入一个全局类
$obj=new namespace\Another;//实例化foo\Another对象
$obj=new Another;//实例化My/Full/Classname对象
NSname\subns\func();//调用My/Full/NSname/subns/func();
$a=new ArrayObject(array(1));//实例化ArrayObject对象
?>
2.一行包含多个use语句
<?php
use My\Full\classname as another,My\Full\NSname;
$obj=new Another;// 实例化 My\Full\Classname 对象
$a='Another';
$obj=new $a;//实例化一个Another对象
NSname\subns\func();// 调用函数 My\Full\NSname\subns\func
?>
12.7 后备全局函数/常量
在一个命名空间中,当PHP遇到一个非限定的类、函数或常量名称时,使用不同的优先策略来解析名称。类名称总是解析到当前命名空间。所以当访问系统内部或者不包含在命名空间的类名称时,必须使用完全限定名称。
如果当前命名空间不存在该函数或常量,PHP会退而使用全局空间的函数或常量。
<?php
namespace A\B\C;
class Exception extends \Exception {}
$a = new Exception('hi'); // $a 是类 A\B\C\Exception 的一个对象
$b = new \Exception('hi'); // $b 是类 Exception 的一个对象
$c = new ArrayObject; // 致命错误, 找不到 A\B\C\ArrayObject 类
?>
12.8 关于全局空间
在名称前加前缀\表示该名称是全局空间的名称,即使该名称也位于其他命名空间。
<?php
namespace A\B\C;
/* 这个函数是 A\B\C\fopen */
function fopen() {
/* ... */
$f = \fopen(...); // 调用全局的fopen函数
return $f;
}
?>
12.9 命名空间的寻找顺序
<?php
namespace A;
use B\D, C\E as F;
// 函数调用
foo(); // 首先尝试调用定义在命名空间"A"中的函数foo()
// 再尝试调用全局函数 "foo"
\foo(); // 调用全局空间函数 "foo"
my\foo(); // 调用定义在命名空间"A\my"中函数 "foo"
F(); // 首先尝试调用定义在命名空间"A"中的函数 "F"
// 再尝试调用全局函数 "F"
// 类引用
new B(); // 创建命名空间 "A" 中定义的类 "B" 的一个对象
// 如果未找到,则尝试自动装载类 "A\B"
new D(); // 使用导入规则,创建命名空间 "B" 中定义的类 "D" 的一个对象
// 如果未找到,则尝试自动装载类 "B\D"
new F(); // 使用导入规则,创建命名空间 "C" 中定义的类 "E" 的一个对象
// 如果未找到,则尝试自动装载类 "C\E"
new \B(); // 创建定义在全局空间中的类 "B" 的一个对象
// 如果未发现,则尝试自动装载类 "B"
new \D(); // 创建定义在全局空间中的类 "D" 的一个对象
// 如果未发现,则尝试自动装载类 "D"
new \F(); // 创建定义在全局空间中的类 "F" 的一个对象
// 如果未发现,则尝试自动装载类 "F"
// 调用另一个命名空间中的静态方法或命名空间函数
B\foo(); // 调用命名空间 "A\B" 中函数 "foo"
B::foo(); // 调用命名空间 "A" 中定义的类 "B" 的 "foo" 方法
// 如果未找到类 "A\B" ,则尝试自动装载类 "A\B"
D::foo(); // 使用导入规则,调用命名空间 "B" 中定义的类 "D" 的 "foo" 方法
// 如果类 "B\D" 未找到,则尝试自动装载类 "B\D"
\B\foo(); // 调用命名空间 "B" 中的函数 "foo"
\B::foo(); // 调用全局空间中的类 "B" 的 "foo" 方法
// 如果类 "B" 未找到,则尝试自动装载类 "B"
// 当前命名空间中的静态方法或函数
A\B::foo(); // 调用命名空间 "A\A" 中定义的类 "B" 的 "foo" 方法
// 如果类 "A\A\B" 未找到,则尝试自动装载类 "A\A\B"
\A\B::foo(); // 调用命名空间 "A" 中定义的类 "B" 的 "foo" 方法
// 如果类 "A\B" 未找到,则尝试自动装载类 "A\B"
?>
13.PHP面向对象
13.1 类定义
格式如下:
<?php
class phpClass {
var $var1;
var $var2 = "constant string";
function myfunc ($arg1, $arg2) {
}
}
?>
注意:函数只能通过该类及实例化的对象来访问,可以在类内部实例化对象:
<?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;
}
}
?>
$this代表自身的对象。
13.2 类的对象
格式:
$obj=new Classname;
13.2.1 调用成员方法
格式:
$obj->funcname($var);
13.3 构造函数与析构函数
13.3.1 构造函数
用于对对象的初始化。,在new对象的时候直接传参以实现初始化。
格式:
<?php
class ClassName{
var $var1;
var $var2;
function __construct($varm,$varn){
this->$var1=$varm;
this->$var2=$varn;
}
}
$obj=new ClassName('a','b');//构造对象且对象的属性被初始化
?>
13.3.2 析构函数
在对象结束生命周期时,系统会自动执行析构函数。
格式:
void __destruct(){}
13.4 类的继承
格式:
class Child extends Parent{
//statement
}
举个例子:
<?php
// 子类扩展站点类别
class Child_Site extends Site {
var $category;
function setCate($par){
$this->category = $par;
}
function getCate(){
echo $this->category . PHP_EOL;
}
}
?>
子类继承带有参数的父类的构造方法:
class students{
var $name,$age,$sex;
function __construct($name,$age,$sex){
$this->name = $name;
$this->age = $age;
$this->sex = $sex;
}
}
class master extends students{
var $hobby,$address;
function __construct($name, $age, $sex,$hobby,$address){
parent::__construct($name, $age, $sex);
$this->hobby = $hobby;
$this->address = $address;
}
}
13.4.1 方法的重写(override)
继承后在子类中可以对父类的同名方法进行改写以满足需求。就不多说了。
13.5 访问控制
PHP通过在类成员前添加关键字public,protected,private来实现对属性或方法的访问控制。
- public:公有的类成员可以在任何地方被访问。
- protected:受保护的类成员则可以被其自身以及其子类和父类访问。
- private:私有的类成员则只能被其定义所在的类访问。
13.5.1 属性的访问控制
类的属性必须定义为三者之一。如果用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
?>
13.5.2 方法的访问控制
类中的方法可以被定义为三者之一,如果没有关键字,默认为public。
子类继承父类的私有方法时后,需要调用时必须通过父类的方法调用。
举个例子:
<?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
?>
13.6 接口
使用接口(interface),可以指定某个类必须实现哪些方法,但不需要定义这些方法的具体内容。
接口是通过 interface 关键字来定义的,就像定义一个标准的类一样,但其中定义所有的方法都是空的。
接口中定义的所有方法都必须是公有,这是接口的特性。
要实现一个接口,使用 implements 操作符。类中必须实现接口中定义的所有方法,否则会报一个致命错误。类可以实现多个接口,用逗号来分隔多个接口的名称。
格式:
<?php
interface Itfc{
function func1($var1,$var2);
function func2($var);
}
class cls implements Itfc{
function func1($var1,$var2){
//statements;
};
function func2($var){
//statements;
};
}
?>
13.7 常量
用const定义常量。
13.8 调用类的方法的方式
13.8.1 直接用类名调用
$className::FunctionName();
13.8.2 用变量动态调动类
$var="classname";
$var::funcname();
13.8.3 对类实例化访问对象的方法
$obj=new classname();
$obj->funcname();
13.9 抽象类
任何一个类,如果它里面至少有一个方法是被声明为抽象的,那么这个类就必须被声明为抽象的。
定义为抽象的类不能被实例化。
被定义为抽象的方法只是声明了其调用方式(参数),不能定义其具体的功能实现。
继承一个抽象类的时候,子类必须定义父类中的所有抽象方法;另外,这些方法的访问控制必须和父类中一样(或者更为宽松)。例如某个抽象方法被声明为受保护的,那么子类中实现的方法就应该声明为受保护的或者公有的,而不能定义为私有的。
抽象类和抽象方法的定义用关键字abstract,放在访问控制符之前。
<?php
abstract class AbstractClass
{
// 强制要求子类定义这些方法
abstract protected function getValue();
abstract protected function prefixValue($prefix);
// 普通方法(非抽象方法)
public function printOut() {
print $this->getValue() . PHP_EOL;
}
}
class ConcreteClass1 extends AbstractClass
{
protected function getValue() {
return "ConcreteClass1";
}
public function prefixValue($prefix) {
return "{$prefix}ConcreteClass1";
}
}
class ConcreteClass2 extends AbstractClass
{
public function getValue() {
return "ConcreteClass2";
}
public function prefixValue($prefix) {
return "{$prefix}ConcreteClass2";
}
}
$class1 = new ConcreteClass1;
$class1->printOut();
echo $class1->prefixValue('FOO_') . PHP_EOL;
$class2 = new ConcreteClass2;
$class2->printOut();
echo $class2->prefixValue('FOO_') . PHP_EOL;
?>
输出:
ConcreteClass1
FOO_ConcreteClass1
ConcreteClass2
FOO_ConcreteClass2
子类方法可以包含抽象方法中不存在的可选参数。
<?php
abstract class AbstractClass
{
// 我们的抽象方法仅需要定义需要的参数
abstract protected function prefixName($name);
}
class ConcreteClass extends AbstractClass
{
// 我们的子类可以定义父类签名中不存在的可选参数
public function prefixName($name, $separator = ".") {
if ($name == "Pacman") {
$prefix = "Mr";
} elseif ($name == "Pacwoman") {
$prefix = "Mrs";
} else {
$prefix = "";
}
return "{$prefix}{$separator} {$name}";
}
}
$class = new ConcreteClass;
echo $class->prefixName("Pacman"), "\n";//Mr.Pacman
echo $class->prefixName("Pacwoman"), "\n";//Mrs.Pacwoman
?>
13.10 Static关键字
用于声明静态属性/方法。
13.10.1 静态属性
不能通过实例化对象用->访问,格式:
classname::var;//类名::变量名
13.10.2静态方法
能通过实例化对象访问,也可以不实例化,直接调用。
伪变量$this在静态方法中不可用。
实例化用法:
$obj=new classname();
$obj->funcname();
13.11 Final关键字
用于声明类和方法。
如果父类的方法被声明为final,子类无法override.
如果一个类被声明为final,不能被继承。
13.12 调用父类构造方法
PHP不会在子类中自动调用父类的构造方法,要执行父类的构造方法,需要在子类的构造方法中调用parent::__construct().
<?php
class BaseClass {
function __construct() {
print "BaseClass 类中构造方法" . PHP_EOL;
}
}
class SubClass extends BaseClass {
function __construct() {
parent::__construct(); // 子类构造方法不能自动调用父类的构造方法
print "SubClass 类中构造方法" . PHP_EOL;
}
}
class OtherSubClass extends BaseClass {
// 继承 BaseClass 的构造方法
}
// 调用 BaseClass 构造方法
$obj = new BaseClass();
//输出:BaseClass 类中构造方法
// 调用 BaseClass、SubClass 构造方法
$obj = new SubClass();
/*输出:
BaseClass 类中构造方法
SubClass 类中构造方法
*/
// 调用 BaseClass 构造方法
$obj = new OtherSubClass();
//输出:BaseClass 类中构造方法
?>
到这里PHP初级学习就结束啦,其实内容都是W3school和菜鸟教程的,我只是进行了整理来加深印象。
最近应该是没有时间学中级教程了,因为报名了csp考试,还有一个月,该复习java语法了,下面会出一个复习Java语法的blog,加油啊!!
碎碎念: 书山有路勤为径,学海无涯苦作舟…… 自己选的路,跪着也要走下去。