《小白7天入门PHP Web开发》系列文章,面向单纯善良的完全不懂Web开发编程的入门速成课程,小白们如果感兴趣可以研读此系列文章,也可以连线提问。各路大神有何指教还请指点一二。希望各路大神手下留情,注意维护自己的身份和形象。拜谢各位。
上一篇文章我们学会了使用简单的CSS完成了对HTML页面的修饰和美化布局,以及以表单提交验证为例的JS的基本使用,这节我们开始尝试使用PHP来做后端处理表单提交后的相关操作。
一、关于PHP的概念
对于PHP的基础概念,作为小白入门的我们,只需要记住一句话就可以了,那就是
PHP全称为 PHP: Hypertext Preprocessor(更名前是 Personal Home Page ),中文名字叫超文本预处理器,是一种开源脚本编程语言,是常用的web开发语言(从旧名称就可以看出)。这里我们需要了解一个概念:静态网站和动态网站。
1、静态、动态所描述的是页面是否能动吗?
当然不是的!拿我们前面几天的文章写成的HTML网页页面来说,她有动(交互)的东西吗?有,不记得了吗?我们用JS做了表单验证,以及表单提交也有交互的过程,但这些都不代表网页是动态网页,包括动图、视频播放等网页上能动的东西,都不能代表网页是动态的。动静态网页所描述的是:内容。网页内容是否根据不同用户或不同场景有所不同,无,则静,有则,动。
举个例子~!
我们前面写得HTML网页页面,无论谁打开什么时候打开,页面和内容那都是一样的,也就是“死”的,一旦生成,就像我爱你一样一辈子都不会变,这就是静态。
我们不同的人登录到我大知乎,登录的账号显示的昵称名字和推荐的内容题目,那都是千篇不一律,不一样的,根据不同用户或不同场景渲染的页面内容不一样,总之就是变动的,这就是动态。
2、PHP就是帮助实现动态网站的非常好的选择
PHP作为最好的WEB编程语言之一(谦虚点,低调点),有很多显而易见的特点,比如语法简单易学习、开发效率高、非常适合WEB开发、社会人才需求大等。PHP可以轻松实现我们 上一篇文章 的表单提交和交互。
了解以上内容,记住更佳,接下来我们开始先了解一下PHP的语法和代码结构。
二、PHP的基础语法
1、基本写法
<?php
/*
* PHP代码通常被包含在这个标签中
* 开始标签是 <?php * 结束标签是 ?>
* 如果文件中只有PHP代码,没有任何别的东西,结束标签可以不要,这种情况下也建议
* 不要(避免页面输出一些空串影响页面)
*/
// PHP 代码写在这里,如下面
echo “Hello PHP, hello web”; // 在页面上输出字符串 Hello PHP, hello web
?>
2、运行环境
PHP的运行需要有自己的运行环境,浏览器直接打开文件是不行滴,浏览器直接打开的都是静态资源。所以我们先搞个简单的运行环境。
因为我们是入门,不是小白就是新手,建议开发环境(就是你自己在你电脑上捣鼓写代码运行测试等等的地方)直接使用集成(把PHP和服务器相关的都合在一起)的开发环境软件,本文推荐使用 phpStudy,可以去官网下载一个最新版,在windows上直接打开安装即可。
phpStudy V8.0下载(Win64位) – 官方最新版本(不断更新)-php中文网工具下载
phpStudy V8.0下载(Win32位) – 官方最新版本-php中文网工具下载
根据你系统的位数选择对应的版本下载根据他们的文档说明进行安装即可。他们都有教程的,注意看哈,有问题再留言问我。(我们目前到这节课,只需要安装好php和nginx服务器即可)
安装就绪后,运行软件,我们就可以看到“网站”栏里面有一个默认的网站域名,localhost ,我们点击“管理”,“打开根目录”文件夹,在文件夹里新建一个文件(可以新建文本文档,再修改文件名)hello.php,打开编辑这个文件,把上述代码复制或者手敲进去(建议手敲一遍代码)。
这里再推荐一个轻量级,启动块使用方便的适合新手也适合老手的编辑器,个人比较喜欢用,我们暂时也不用深究工具选择,等你学习到一定程度了,自然而然就会主动了解和选择了。那么这个编辑器就是sublime text 3 点击就可以下载了,当然你直接用我们之前提到的前端神器VSCode也是可以的。
如果你安装了sbt(sublime text的简称),可以直接用编辑器新建文件,保存到对应的根目录即可。
文件代码写好保存好放到对应位置,phpStudy也启动了,phpStudy里面的nginx也启动了,那么,现在,打开浏览器,在浏览器输入 localhost/hello.php,即可访问到。结果如下图:
图 2-1 浏览器运行效果图至此,我们了解了PHP文件的基本编写和运行过程:
编写php代码 =》 运行php服务器环境(如phpStudy中的nginx和php7.0) =》浏览器访问php文件(事实上我们还可以通过命令行,用php命令执行php文件,知道就可以了)
3、php的基本语法
语法就像我们学语文里面的段落、句子、词语一样,有一定的规律和结构。关键字(词语)组成语句(句子),语句组成代码段落和结构(段落)。
我们以 “用户输入学生成绩,根据学生成绩对学生评级并输出”为案例讲解php的语法。
首先,是HTML页面,一个包含简单表单的页面,方便用户输入学生成绩并提交到后端服务器的php代码进行处理。(这个页面可以先尝试自己实现以下,效果如下即可)
图 2-2 表单页面效果记得要自己尽可能的去编写HTML代码去实现上面的页面哦,这个页面很简单,只要你认真看了前面的内容,就真的so easy~!
当然,我还是会给代码给你参考的,但不代表我的是唯一答案,你知道的,穿衣服的方式有很多种。
<!– score.html –>
<!– 使用 localhost/score.html 访问或直接用浏览器打开文件 –>
<!– score.html文件应与后续.php文件在同一个目录下 –>
<!DOCTYPE html>
<html>
<head>
<meta charset=“utf-8”>
<meta http-equiv=“X-UA-Compatible” content=“IE=edge”>
<title>成绩转评级</title>
<style type=“text/css”>
/*通用样式*/
* { font-size: 14px; margin: 0; padding: 0; }
/*说明部分样式*/
.explain { background-color: #f4f4f4; margin-top: 100px; padding: 20px 0px; }
.block { text-align: left; width: 400px; margin: 0 auto; }
.block ul { list-style: none; }
/*表单部分样式*/
.form { width: 400px; margin: 0 auto; margin-top: 20px; }
.form input, .form button {
height: 36px;
box-sizing: border-box;
margin-top: 10px;
padding: 5px 10px;
}
.form input { width: 100%; }
.form button { width: 100px; }
</style>
</head>
<body>
<div class=“explain”>
<div class=“block”>
<ul>
<li>1、 学生成绩90分(含)以上,评级为A</li>
<li>2、 学生成绩在80分(含)以上,90分以下,评级为B</li>
<li>3、 学生成绩在60分(含)以上,80分以下,评级为C</li>
<li>4、 学生成绩在60分以下,评级为D</li>
</ul>
</div>
</div>
<div class=“form”>
<form action=“scorelevel.php” method=“get” accept-charset=“utf-8” target=“_blank” onsubmit=“return checkform()”>
<input type=“text” name=“study_name” value=“” placeholder=“请输入学生姓名”>
<input type=“text” name=“study_score” value=“” placeholder=“请输入学生成绩”>
<br>
<button type=“submit”>检测评级</button>
</form>
</div>
<script>
function checkform() {
var study_name = document.getElementsByName(study_name)[0].value;
var study_score = document.getElementsByName(study_score)[0].value;
if ( !(study_name && study_score) ) {
alert(学生姓名和学生成绩不能为空);
return false;
}
}
</script>
</body>
</html>
这个HTML文件叫 score.html,里面主要是一个表单与后端php文件交互,所以我们要新建一个在action属性里面的那个名字的php文件
<form action=“scorelevel.php” method=“get” accept-charset=“utf-8” _blank=“self”>
用sbt新建 scorelevel.php,注意这里建议 保持score.html和scorelevel.php同在根目录下(action里面其实就是php文件的地址,所以你能保证路径对就可以),以下是php文件的代码,你大可以先复制进去我们再来逐个了解。
<?php
/**
* 我们以 “用户输入学生成绩,根据学生成绩对学生评级并输出” 的功能需求来做示例 * 需求的基本内容:
* 学生成绩90分(含)以上,评级为A
* 学生成绩在80分(含)以上,90分以下,评级为B
* 学生成绩在60分(含)以上,80分以下,评级为C * 学生成绩在60分以下,评级为D
*/
// 首先考虑,成绩从哪里来?用户输入提交过来的
$study_name = isset($_GET[study_name]) ? $_GET[study_name] : ;
$study_score = isset($_GET[study_score]) ? $_GET[study_score] : ;
// 初始化评级
$level = 未知;
$level_label = 未知;
// 检测姓名和分数是否为空
if ( $study_name == || $study_score == ) {
echo 学生姓名和学生成绩未知,请检查提交的数据是否为空;
die;
}
// 根据分数给学生评级if ( $study_score >= 90 ) {
$level = A;
} elseif ( $study_score >= 80 && $study_score < 90 ) {
$level = B;
} elseif ( $study_score >= 60 && $study_score < 80 ) {
$level = C;
} elseif ( $study_score < 60 ) {
$level = D;
} else {
$level = 未知;
}
switch ( $level ) {
case A:
$level_label = 优秀;
break;
case B:
$level_label = 良好;
break;
case C:
$level_label = 及格;
break;
case D:
$level_label = 差;
break;
}
echo 学生 .$study_name. 的成绩为 . $study_score .,评级为:.$level.(. $level_label .);
die;
现在你在HTML页面上输入姓名和成绩,点击按钮“检测评级”,会打开一个新的页面,这个页面就是php文件的页面,但是他是处理过我们提交的数据最后输出内容到页面上来的。
图 2-3 表单提交到scroelevel.php后的页面效果3.1 php文件代码标签语法:第一点,当然我们写php代码的时候,要有一定的基础规范,正常情况下,php代码应该在“<?php // php代码 ?>”标签内,当整个文件只有php代码时,结束标签“?>”是可以并且建议忽略不写的,反过来说标签内只能是php代码,每一条php语句必须以半角英文分号(;)结束。然而需要注意的一点是,php代码在处理字符串的时候,是可以把HTML、CSS、JS代码写进去的。(字符串是指任意一串字符、代码、文本等,在php代码中表现为在单引号和双引号里面的都是字符串,如上述代码中我们最后 echo后面的内容)
3.2 变量:第二点,前端HTML页面表单提交过来的数据,我们要接收,就需要变量这个东西了,变量是储存计算结果或能表示值的抽象概念,简单理解就是用来表示某个值或者某个数据的一个概念。变量通过声明或定义变量名,由代码去向计算机申请内存,来存储变量名所对应的值或数据,变量名由 英文开头(必须),和数字、下划线共同组成,你可以自己选择(一般命名有两种方式,一种就是代码里用的,用下划线将不同含义的词分开,还有一种是第二个单词起首字母大写,叫驼峰法,如$studyName)。比如代码中的
$study_name = isset($_GET[study_name]) ? $_GET[study_name] : ;
$study_score = isset($_GET[study_score]) ? $_GET[study_score] : ;
// 初始化评级
$level = 未知;
php中声明和定义变量使用 $ 美元符号,后面紧跟着变量名称,例如上面的 $s
字符类型:可以理解为字符或字符串,如 $var = string;
整型:可以理解为整数,包括正负数和0,都是整型,如 $var = 1; $var = –2;
浮点型:可以理解为有小数的数字类型,如 $var = 1.12;
布尔类型:可以理解为只有真、假两个值,如 $var = true; $var = false;
数组:是一种数据结构,用于存储多个不同的值,如 $var = array(我是值1, 我是值2, 5);
对象:是一种数据结构,是类的实例,对象存储了很多值,包括属性变量、方法等
(后面我们会专门讲面向对象的时候讲到对象)
3.3 比较运算和数学运算:第三点,因为我们需要通过不同的分数不同的条件来换算出评级,所以要进行判断和比较,比较运算,顾名思义,就是要对多个值或变量进行比较,必出大小、是否相等、是否不相等等,比较运算的结果是布尔值,如
$study_name == || $study_score ==
其中符号 || 是或者的意思,只要满足其中任何一个条件就可以继续,符号在回车键上方,这个语句的意思就是:如果变量$study_name为空字符串或变量$study_score为空字符串的话就是真的;如果要两个或多个条件同时满足时用 && 符号连接。
第四点,当我们需要做一些数学运算的时候就用到php的数学运算,其实就跟我们现实中的数学运算如出一辙,加、减、乘、除、取余、取模等是常见的数学运算,其他一些稍复杂的数学运算,php也提供了相关的内置函数(php自己封装了一些列标准的函数,函数是代码的一种封装方式,先有个概念在心中即可)来处理。
加法运算:$a = 1 + 1; // 结果是 $a = 2
减法运算:$b = $a – 1; // 结果是 $b = 1乘法运算:$c = $a * $b; // 结果是 $c = 2
除法运算:$d = 5 / $c; // 结果是 $d = 2.5
取余/取模:$e = 5 % $c; // 结果是 $e = 1,就是余数,如果除数是负数,余数也是负数
3.4 分支语法,条件判断 if…elseif…else…
第五点,当我们做不同的比较得到不同的结论后,会有不同的评级处理,这就好比是在岔路口有不同的岔路,我们要对其分支进行一个选择(这个选择基于比较结果),于是我们就需要以下的php语法的代码分支结构来实现
if ( $study_score >= 90 ) {
$level = A;
} elseif ( $study_score >= 80 && $study_score < 90 ) {
$level = B;
} elseif ( $study_score >= 60 && $study_score < 80 ) {
$level = C;
} elseif ( $study_score < 60 ) {
$level = D;
} else {
$level = 未知;
}
if…elseif…else…主要用于处理不同条件下,处理的方式或者变量的值不一样的情况,就像找女朋友一样,列了一堆条件,挨个去筛选,直到符合条件时就交往,不符合继续找。主要结构如上。条件明确时,使用if或elseif+圆括号,括号里面是条件,即比较运算,当结果是真(true)时就执行对应花括号里面的代码。比如
if ( 女孩身高 > 170 ) {
echo “我要和她交往”;
} else {
echo “孤独终老”;
}
如果女孩的身高大于170cm,那就交往,否则拒绝交往(你可能要孤独终老了)。当只有一个明确条件,其他都不清楚的时候,中间是可以没有elseif的,直接if…else…即可。
3.5 分支语法,switch
第六点,其实跟第五点差不多
switch ( $level ) {
case A:
$level_label = 优秀;
break;
case B:
$level_label = 良好;
break;
case C:
$level_label = 及格;
break;
case D:
$level_label = 差;
break;
}
switch常用于有多个分支并且有确定值分类比较简单值的时候,上述代码时我们要对评级分别给予描述。基本语法结构如上,下面也再做个解释
switch ( $level ) {
// 分支关键字 switch 必须的,加圆括号和花括号,圆括号里面是变量或者一个有明确计算结果的表达式 case A: // 每一个分支都用 case 值:来开始
/*这里写代码和业务逻辑*/
break; // 每一个分支处理完代码业务逻辑,要跳出当前分支
case B:
$level_label = 良好;
break;
case C:
$level_label = 及格;
break;
case D:
$level_label = 差;
break;
}
switch和if…else…在很多情况下是可以互相替代的,并且可以随便嵌套,就是你中有我我中有你的这种感觉,因为switch和if…else..本身也是组成代码业务逻辑的一部分,当然可以放在彼此怀(dai)里(ma)了(li)
3.6 输出和打印
第七点,当我们
echo 学生 .$study_name. 的成绩为 . $study_score .,评级为:.$level.(. $level_label .);
die;
这里的代码中我们使用了 echo 这个关键字(php语法,php中预留了一些自用的单词),echo后面可以输出非数据结构类型的其他类型变量或值,比如,字符、数字(整型和浮点型)、布尔值等。而要输出打印数组(array)、对象(object)则需要用到以下两个函数
print_r($array); // 通常用于数组打印
var_dump($object); // 可以输出打印所有类型,会有类型提示灯详细信息print char; // 与echo类似
常用的基本上就是我们以上者四种了,可以用来输出内容数据给用户看,也可以用来进行简单的代码调试(作用很大)。
3.7 循环结构
第八点,我们现在每次处理的是一条学生的成绩数据,如果需要处理多条的时候呢?我们就需要用到循环结构语法了,也就是不断重复的去执行语句。首先,我们假设,需要同时处理5个学生的成绩,我们用数组(用于存储多个不同的值)定义如下
// php中数组的定义如下
// 使用array()来定义数组,数组的值也可以是数组
// 有键名(如下面的name和score用来描述后面的值是什么样的值)和值对的
// 也有没有键名只有值得,下面的值array(name => 章五二, score => 85)就是没有键名的// 键名和值用符号 => 连接,数组里的每一个项(值)后面用逗号(,)结束,最后一项可以不用
// 数组只有一层(如 array(1,2,3))叫一维数组,有两层(如下面的)叫二维数组,以此类推$score_arr = array(
array(name => 章五二, score => 85),
array(name => 李小狗, score => 65),
array(name => 孙儿了, score => 99),
array(name => 韦小宝, score => 59),
array(name => 任之初, score => 88)
);
// 或用短数组的方式来定义,就是中括号 [] 代替 array(),在php5.4以上的版本支持了,如下
$score_arr = [
[name => 章五二, score => 85]
];
// (数组的索引下标从0开始,第一个值下标是0,第二个是1,以此类推)$score_arr[0]; 数组)的score对应的分数值$score_arr[0][score];
现在数组有了,我们要进行批量处理的时候,就可以采用循环的方式,数组循环我们通常用
foreach(数组 as 键 => 值) {}
的方式
foreach ( $score_arr as $key => $value ) {
// 此时的 $value 就是数组的每一个值,从0(第一个)开始 // 如array(name => 章五二, score => 85)
echo 学生 . $value[name] . 的成绩为 . $value[score] . <br>;
}
/*
学生 章五二 的成绩为 85
学生 李小狗 的成绩为 65
学生 孙儿了 的成绩为 99
学生 韦小宝 的成绩为 59
学生 任之初 的成绩为 88*/
还有两个常用循环结构
for(初始值; 条件判断表达式; 改变条件) { // 代码逻辑 }
// 和
初始值
while(条件判断表达式) {
// 代码逻辑
改变条件
}
注意有三要素:初始值、条件判断、改变条件,同时注意for里面用的是分号而不是逗号。具体写法如下
// 以从1加到100为例,你想说首尾相加乘以50就好了,还要什么代码执行,哦豁,那么我们就用乘的吧
// 从1乘到100,hiahiahia
// $i不断的变化,带来了循环和循环结束的可能性,每一轮循环,$i的值都在变化$total = 1; // 定义变量存储最终结果
for ($i=1; $i <= 100; $i++) {
$total = $total * $i; // 当对变量自身进行数学运算时可以简写,如 $total *= $i;}
// 或用 while
$total = 1;
$i = 1;
while ($i <= 100) {
$total *= $i;
$i++;
}
// 补充说明: $i++是自增1,同理$i–是自减1,同时符号放在前面也是可以的,结果一样,如++$i、–$i// 但他们有所区别,你可以简单理解为,符号在前面的,是先运算再使用,在后面的是先使用再运算,比如
$i = 1;
$val = $i++; // $val = 1, $i = 2
$i = 1;
$val = ++$i; // $val = 2, $i =2
// 好好体会一下
至此,你需要了解的PHP入门的基本语法就差不多了,你可以自己尝试谢谢别的东西,比如模拟和用户的对话,用户选择问题提问,你针对问题返回输出不同的答案给用户等等。Just try it~!恭喜你,真的入门了。如果你还不满足,那么请接着往下看,以后我们都尽量用下面的知识来写php代码哦。
三、PHP函数和类
1、函数
php函数分为内置函数和自定义函数,函数是一种功能的封装,大大提高了代码的复用率,避免了代码的冗余。
PHP 的真正威力源自于它的函数。在 PHP 中,提供了超过 1000 个内建的函数。是不是听起来就有点炸。那么什么时候使用函数呢?一般要进行重复使用同样或类似的代码的时候就需要用到函数,函数来封装这部分代码,放在一处,处处可用,业务代码更简洁了,还能少些代码,同时功能解构了,互不影响,多好,何乐而不为。
内置函数,只要你想用就可以直接用,包括我们上面接触到的输出用的两个函数 print_r() 和 var_dump(),可以直接使用,函数的调用方式就是
函数名(参数)
函数名和变量名的命名规则一致,那参数是什么呢?
var_dump(我就是参数,值);
非常简单的去理解的话,参数就是函数调用的时候括号里面的东东,比如上面的 我就是参数,值,这整个就是参数。参数的作用就是将函数外部的变量、值等传递到函数内部使用,参数也分实参和形参,作为入门理解,我们简单的理解为,实参是外部传递到函数内部的时候的参数,形参则是函数定义的时候,定义的参数列表。
// 假装我是源码里面的函数声明
function var_dump($input) { // 这里是代码逻辑实现 }
// 这里声明了函数var_dump,括号里面的就是形参了,$input
// 我们调用var_dump$input = i am the input string;
var_dump($input);
// 这里调用时候传入的参数$input就可以理解为实参
由于php内置了很多函数,可以非常方便的使用,我们这里不详细列举,大家可以自己去了解下,后面我们用到的都会做对应讲解。
当内置函数不能满足我们业务逻辑需求的时候,我们就需要自定义函数了。定义函数使用 function 关键字,基本格式如下(上面其实我们已经见过她了)
function 函数名(参数1, 参数2, …参数n) {
业务逻辑代码
}
函数定义五要素:关键字function、函数名、圆括号和参数、花括号、花括号内的业务逻辑代码。
那么什么情况下要去封装定义一个函数呢?我们拿我们在讲循环结构的时候,进行的累乘计算的例子来讲,我们现在是从1开始累乘每次自增1的值,如果有一天需求增加了从2开始累乘每次自增2的值的时候,我们就得写成下面这个样子
// 第一个需求$total_1 = 1;
$i_1 = 1;
while ($i_1 <= 100) {
$total_1 *= $i_1;
$i_1++;
}
// 第二个需求
$total_2 = 2;
$i_2 = 2;
while ($i_2 <= 100) {
$total_2 *= $i_2;
$i_2 += 2;
}
然后,需求又变了,增加一个从10开始累乘每次自增10的值,不仅如此,还要把原来的从1开始的改成从5开始,(不要以为这样的需求不会出现,你以后干这一行你就会发现,无处不在,产品的思维不是你我能够理解的)如果按上面的写法,要继续加代码,并且很明显的发现,几个需求的代码几乎是一样的,只有两个东西不一样,这就很尴尬了,不断写差不多的东西,修改的时候还得修改很多地方,比如从1开始改成从5开始累乘3,你需要修改的地方有哪些,你自己数数。
那么事情发展到了这个地步,难道没有办法解决吗?怎么,你忘了?我们说的函数啊。
// 按函数声明的格式,我们写来个框架function multiply() {}
然后我们观察需求发现,经常变动的有两个东西,一个是起始值,一个是自增值,那么这种变动的东西,我们可以让她以后作为参数传到函数里面去。
// 添加形参
// $multiplicand 被乘数(起始值)// $increment 自增值
function multiply($multiplicand, $increment) {}
然后就是把代码逻辑放到函数体(花括号内部分)内,使用参数来处理计算结果
function multiply($multiplicand, $increment) {
$total = $multiplicand;
$i = $increment;
while ($i <= 100) {
$total *= $i;
$i += $increment;
}
}
然后我们把结果从函数里面返回到函数外面,用 return 即可。
function multiply($multiplicand, $increment) {
$total = $multiplicand;
$i = $increment;
while ($i <= 100) {
$total *= $i;
$i += $increment;
}
return $total;
}
这样我们上面的代码就可以变成
/*function.php 专门放function函数的地方,也可以和业务代码放在一起*/
function multiply($multiplicand, $increment) {
$total = $multiplicand;
$i = $increment;
while ($i <= 100) {
$total *= $i;
$i += $increment;
}
return $total;
}
/*code.php*/
// 使用 require 来包含其他 php 代码
require function.php;
echo multiply(1,1);
echo multiply(2,2);
是不是看出来,在具体业务代码的code.php中,代码更简洁了,而且封装的函数multiply可以复用了。多好,多美好~!这里因为例子规模较小,优势可能你觉得没那么明显,慢慢等你长(shen)大(ru)了会知道的,不着急,一个阶段做一个事情嘛。
函数解决了代码复用的基本问题。
2、类和对象
当需要封装的函数越来越多,越来越杂的时候,管理起来就开始变得困难,可读性也更难了。你可能想到用不同文件来存放不同的函数,然后用到的时候去分别包含(require或include)进来,good~!非常优秀,说明你在代码复用问题的解决上已经迈出了思考的一步~!厉害了我的哥哥姐姐们~!
不过!如果函数非常多的时候,有没有想过你自己都可能忘了文件里哪个函数是声明定义过的,我现在写一个新的函数是不是名字被使用过?为什么这么考虑,因为两个函数名一样的函数被包含或写到同一个文件里的时候,php运行或发生致命错误,也就是不能重复声明或定义名字一样的函数。
How to 解决这个问题呢?所以有了类和方法的概念。请仔细研读一下下面的文字,从基本面上了解类、对象、方法、属性
在学校里,学生、老师是两群不同的群体,简单说就是两类人,这个时候,学生是一类,老师是一类,这就是类
在学生或老师的某一类里,每一个学生或老师,都是各自群体里的某一个个例,或者叫实际的例子,简称实例(话糙理不糙),比如张五、孙三,都是不一样的个体实例,我们就这叫实例化的对象,也就是类(学生群体)的对象(个体实例)
想想看,张五、孙三这两都有些什么共同的静态的东西,就是你有我也有的那种?想到了吗?没想到?不会吧~!身高?体重?是不是?腰围、胸围、臀围是不是?当然都是啊~!我们把这些称为对象的属性
张五、孙三除了有共同的静态的特征,还有一些共同的动态的东西,比如吃,比如喝,还有拉撒等,这些我们都可以称为对象的方法此时此刻的你,我觉得应该对类和对象以及对象的属性、方法有了一定的了解了。还记得上面你想到的把不同方法归类到不同文件吗?这个时候,我们可以把一个类写到一个文件,然后类里面有不同的方法,这样只要类名不同,我们的方法同名也不要紧,因为我们使用类的对象去调用的方法,每一个对象实例那都是不是同一个的。
那么php里面一个类要怎么写呢?我们这里遵循一个规范(很多规范有学术名称,我们这里先不提,你知道就行了),一个文件一个类,类名和文件名要一致,比如我要新建一个学生类
<?php
/**
* Student.php
* 这是一个学生类,类名 Student和文件名Student一致
* 方便读懂和找类的时候更容易找到和区分
*/
/**
* 类声明的基本形式如下
* class 类名 {} */
class Student {
}
学生这一类人有哪些属性(特征)和方法(动作、能力)呢?
<?php
/**
* Student.php
* 这是一个学生类,类名 Student和文件名Student一致
* 方便读懂和找类的时候更容易找到和区分 */
/**
* 类声明的基本形式如下
* class 类名 {}
*/
class Student {
// 身高
public $height;
// 体重
public $weight;
/**
* 吃
*/
public function eat() {
echo I am eatting~!;
}
/**
* 喝
*/
public function drink() {
echo Drinking too much~!;
}
}
就这样,我们写了一个拥有两个方法(类里面的函数我们通常称为方法)和两个属性的学生类。有没有发现,类方法的声明和函数的几乎是一致的,而类属性和变量的声明也几乎是一样的。区别在哪里呢?你们都是明眼人,一看就知道多了个 public,这个关键字,和protected、private,并称类属性或方法的访问类型,也就简单的描述了属性和方法的访问限制
public:定义的属性和方法,在类的内部和外部都可以直接访问使用,她们是公开的。
protected:定义的属性和方法,在类的内部和继承她的子类的内部可以直接访问和使用,她们是对子类公开的,在类之间进行了保护。
private:定义的属性和方法是私有的,只有类内部自己能访问和使用。
那么如何访问类的属性和方法呢?我们新建一个class.php文件来演示类的实例化和属性、方法的访问
<?php
/**
* class.php
*/
// 包含类文件,也就包含了类require Student.php;
// 实例化类,使用 new 类名() 的方式
// 这样就得到了一个学生类Student的对象 $student
$student = new Student();
// 使用对象->的方式访问类的属性和方法
var_dump($student->height);
$student->eat();
既然讲到继承了,我们就继续讲一讲,继承作为类的一大特性之一,能够解决更多的代码耦合的问题,比如同样是学生,男同学和女同学在吃上面也是不一样的,男同学吃饭量大且大口朵颐,女同学量小还温柔细嚼慢咽。这个时候,如果我们在学生类的方法吃里面进行男女生判断再执行不同的操作,如下
<?php
/**
* Student.php
* 这是一个学生类,类名 Student和文件名Student一致
* 方便读懂和找类的时候更容易找到和区分
*/
/**
* 类声明的基本形式如下
* class 类名 {}
*/
class Student {
// 身高
public $height;
// 体重
public $weight;
// 性别
public $sex;
/**
* 每个类都可以声明定义一个构造函数
* 构造函数在实例化的时候就会调用 * 也就是比其他方法会先调用
* 可以接受参数
*/
public function __construct($sex) {
// 在类内部使用 $this 来访问属性和方法
// 访问类属性和方法时的使用方法时:$类对象名->属性或方法,例如下面 $this->sex = $sex; // 把传进来的性别参数赋值给类的sex属性
}
/**
* 吃
*/
public function eat() {
// 根据性别不同来判断吃相 if ( $this->sex == 男 ) {
echo 吃得很香,大口朵颐,毫无人性;
} elseif ( $this->sex == 女 ) {
echo 哇,温柔的细嚼慢咽,好美的画面;
} else {
echo 夹起,塞嘴里,嚼碎,吞咽;
}
}
/**
* 喝
*/
public function drink() {
echo Drinking too much~!;
}
}
突然,需求变了,不是男女来区分吃的方法方式了,而是年级来分,一年级的这么吃,二年级的那么吃…去改代码去吧,不仅要去掉先前的代码,还要新增别的代码,并且,万一原来别的地方使用了男、女吃的方法,那可怎么办,隐患真大,所以我们伟大的先人们发明了类继承
我们新建一个男、女学生类,继承学生类(学生类先还原到最初的样子)
<?php
/**
* Student.php
* 这是一个学生类,类名 Student和文件名Student一致
* 方便读懂和找类的时候更容易找到和区分
*/
/**
* 类声明的基本形式如下 * class 类名 {}
*/
class Student {
// 身高
public $height;
// 体重
public $weight;
/**
* 吃
*/
public function eat() {
echo I am eatting~!;
}
/**
* 喝
*/
public function drink() {
echo Drinking too much~!;
}
}
然后新建男学生类和女学生类(php里面类的继承是只能继承一个父类的)
<?php
require Student.php;
/**
* StudentBoy.php
* 男学生类
* 继承学生类,也就继承了学生类的所有非私有(private)的属性和方法 */
class StudentBoy extends Student {
}
<?php
require Student.php;
/**
* StudentGirl.php
* 女学生类
* 继承学生类,也就继承了学生类的所有非私有(private)的属性和方法 */
class StudentGirl extends Student {
}
使用关键字 extends 来继承类,这样,啥也不用写啥也不用干,就拥有了学生类的所有非私有(private)属性和方法。
<?php
/**
* class.php
*/
// 包含类文件,也就包含了类
require StudentBoy.php;
// 实例化男学生类对象,虽然男学生类没有eat方法,但是继承了学生类,也继承了学生类的eat方法$boy = new StudentBoy();
$boy->eat();
那么继承有了,我们怎么才能够实现不同的性别或年级来执行不同的吃法呢?没错~!(达叔好久不加你…)就是一个叫子类重写父类成员方法的方式,也叫覆盖、覆写。很简单,就是在子类里面重新定义或声明一遍父类的某个方法,这样一来,你实例化子类对象的时候,调用该方法,就会调用子类里面的,那些没有重写父类方法和父类本身的类,依旧可以轻松调用父类的该方法,互不影响,实现解构,解耦。
<?php
require Student.php;
/**
* StudentBoy.php
* 男学生类
* 继承学生类,也就继承了学生类的所有非私有(private)的属性和方法 */
class StudentBoy extends Student {
// 重写父类eat方法
public function eat() {
echo 吃得很香,大口朵颐,毫无人性;
}
}
<?php
require Student.php;
/**
* StudentGirl.php
* 女学生类
* 继承学生类,也就继承了学生类的所有非私有(private)的属性和方法
*/
class StudentGirl extends Student {
// 重写父类eat方法
public function eat() {
echo 哇,温柔的细嚼慢咽,好美的画面;
}
}
就非常方便的能扩展了,并且任何一个类修改将不影响父类,父类修改也不影响子类,新增多少个年级的吃法都是新增某个年级的类,然后重写父类的方法即可。
至此,我们讲解了类、对象、实例化、对象属性、对象方法、类继承、重写父类方法等内容。但其实类和对象里面还有很多东西,后面我们会慢慢接触和讲到。到这里对于入门来说已经够我们喝一壶的了。
最后,给大家留一个问题,用类和方法以及函数的封装来改写我们文初 scorelevel.php 文件关于处理前端提交过来的学生和分数评级的相关代码,练习一下也是可以的。或者在我们类和对象的内容里,你去实现一年级、二年级的类和吃的方法,甚至是喝的方法等。
本文章旨在让你了解PHP的基础语法、PHP如何和前端表单交互、PHP的类和对象、函数等知识,希望你能掌握简单的PHP前后端交互、理解类和函数封装。