PHP与MySQL程序设计 学习笔记 第三章 PHP基础
PHP可将代码嵌入到HTML页面中,要让代码完成任务,必须把页面传递给PHP引擎进行解释,但Web服务器并不传递所有页面,只传递具有特定文件扩展标识(一般为.php)的页面,即使只传递某些页面,效率也很低下,因为每一行都可能是一个php命令,都要处理,因此引擎需要一种确定页面哪部分是php代码的方法,可通过以下方式界定PHP代码:
1.默认语法:
<?php
echo "<p>Some dynamic output here</p>";
?>
2.短标签:
<?
print "This is another PHP example.";
?>
短标签使用比较方便,但为了再分发的php软件不应使用,因为该特性可能会在php.ini中被禁用。
启用短标签语法时,如想快速输出一些动态文本,可使用短路语法:
<?="This is another PHP example.";?>
// 与下面形式的语句等价
<? echo "This is another PHP example."; ?>
<?php echo "This is another PHP example."; ?>
3.某些编辑器处理php采用的转义语法时存在问题,因此php还支持另一种主流的界定形式:
<script>
print "This is another PHP example";
</script>
4.Microsoft ASP页面使用预定义的字符模式将静态内容和动态内容分开,如果你想继续使用这种语法时使用:
<%
print "This is another PHP example";
%>
这种形式的界定符很少被使用,PHP 5.3.0开始已不再支持这种语法。
在一个页面中,php代码与非php代码可多次交替出现。前面php块中的变量都能被记住并由后面的块使用。
注释方法:
1.单行C++语法:
<?php
// 注释
echo "aa";
?>
2.单行shell语法:
<?php
# 注释
echo "aa";
?>
phpDocumentor是一个能将嵌入在源代码中的注释转换为易读的格式(HTML、PDF)的开源项目。它的做法是解析一个应用程序源代码,从中搜索被称为DocBlock的特殊注释,DocBlock用于给代码中的脚本、类、函数、变量等加注释,DocBlock还包含一些人可读的解释,如作者名、代码版本、函数返回值等信息。
3.多行C语法:
<?php
/*
注释1
注释2
*/
echo "aa";
?>
向浏览器输出数据的方法:
1.print语句:
<?php
print("<p> aaa.</p>");
print "<p>aaa.</p>";
?>
虽然该函数正式语法要求使用括号把参数括起来,但也可以省略括号,因为技术上讲,print不是一个函数,而是一个语言结构。print的返回值总是1。
2.echo语句:
函数原型说明它可以接受多个参数,但没必要使用该特性:
<?php
$a = "a";
$b = "b";
echo $a, " and ", $b;
echo "$a and $b"; // 同上,但更简洁
?>
echo()和print()相比,echo()稍快一点,因为它不用返回值,但速度差异很小,可认为选择哪个函数只是编程风格的问题。
3.printf()语句:
可将静态文本和动态信息清晰地分到两个不同的部分组合起来,便于维护,并且还能控制动态信息的格式,如类型、精度、对齐方式、位置。
printf("a integer %d.", 100);
%d是占位符,被称为类型指示符,d指示该位置上放一个整数值,即后面的100,如果传入的是浮点数,则会去掉小数部分取整;如果传入的是字符串"one hundred",会输出0,但如果传入字符串"123food",则会输出123。
%.2f表示小数点后保留两位。
4.sprintf():与printf功能相同,但它将输出赋给字符串,而非直接呈现到浏览器。
$v = -2.10;
echo $v; // 输出-2.1
$v = sprintf("%.2f", $v);
echo $v; // 输出-2.10
标量数据类型(表示一个值的类型,非复合数据类型,其中不含其他数据):
1.布尔值:以数学家乔治·布尔的名字命令,他是信息论创始人之一。只支持两个值TRUE或FALSE,也可用非0值表示TRUE。
2.整型:不包含小数部分的数:
42 // 十进制
0755 // 八进制
0xC4E // 十六进制
所支持的最大整数与平台有关。
3.浮点型:也称为单精度数(float)、双精度数(double)、实数。包含小数部分:
3.14
3.0
8.7e4 // 87000
4.字符串:单引号或双引号界定的连续字符序列。PHP将其视为数组,可通过数组偏移法访问特定的字符:
$color = "maroon";
$parser = $color[2]; // 该变量为r
复合数据类型可用于将多个值聚集起来,表示为一个实体:
1.数组:有索引的数据值集合,每个数组索引(也称为键)引用一个对应的值。php也支持多维数组。
2.对象:
class Appliance {
private $_power;
function setPower($status) {
$this->_power = $status;
}
}
$blender = new Appliance;
以上定义了名为Appliance的数据结构。
将浮点数转换成整数时,小数部分直接去掉。
标量数据类型可将一个非array值转化成array:
$a = 1;
$a = array($a); // $a现在是一个数组,其中只包含一个1
$b = [1, 2, 3];
$b = array($b); // $b不变
任何标量类型都能转换为对象,结果是该变量成为了对象的一个名为scalar的属性:
$a = "a";
$obj = (object)$a;
print($obj->scalar); // 打印出"a"
但如果是复合变量转换成对象,如果是对象,则不变,如果是数组,则其键转换为属性名,对应值转换为属性值。
整数和字符串相加时字符串会转换为整数。
字符串转换为整数时会将字符串开头数字转换为数字而忽略后面的非数字内容,字符串开头的空格、制表符被忽略。字符串转浮点数时也类似。可以识别科学计数法表示的数字:
var_dump(intval("3.14e3adb")); // 输出int(3140)
gettype函数可获取变量的类型:
其返回值有array、boolean、double、integer、object、resource、string、unknown type。
settype函数将变量转换为特定类型:
type可取值为array、boolean、float、integer、null、object、string,转换成功返回true。
确定变量类型的函数:
参数类型mixed表示可以是各种类型。
name可以是array、bool、float、integer、null、numeric、object、resource、scalar、string。
is_numeric函数可检查变量是否是数字或数字字符串:
$a = "1";
is_numeric($a); // 返回true
如果参数var属于该类型,则返回true。
字符串中可通过$后跟变量名来使用变量,如想输出$,需要\
转义。
标识符是变量、函数等各种用户自定义对象的名字,它有以下规则:
1.必须以字母或下划线开头,且只能含数字、字母、下划线、127~255的其他ASCII字符组成。
2.区分大小写。
3.长度任意。
4.不能与php预定义标识符相同。
变量是具有名字的内存位置,其中存有数据。
变量总是以$开头,后跟一个表示变量名的标识符。
php中不需要显式声明变量,其声明和赋值可以同时进行,但最好所有变量都在使用前声明且带有注释。
按值赋值每个变量都拥有表达式赋给它的一个副本,如果希望两个变量指向一个副本,需要通过引用赋值(php 4中引入):
$color = "Hello"; // 按值赋值
$value1 = &$color; // 引用赋值
$value2 =& $color; // 同上
声明变量的位置影响其访问范围,即作用域:
1.局部变量:函数中声明的变量,只能在函数中被访问到,退出函数时,该变量及其值会被撤销。
2.函数参数:与局部变量类似。
3.全局变量:可在程序的任何位置被访问到,如果想访问,需要显式地在函数中将其声明为全局变量:
$somevar = 15;
function addit() {
global $somevar;
$somevar++;
echo "$somevar";
}
addit(); // 输出16
如果省略函数中全局变量的声明:
<?php
$somevar = 15;
function addit() {
$somevar = 0;
$somevar++; // 报错,没有这个局部变量
echo "$somevar" . PHP_EOL; // 输出1
global $somevar;
echo "$somevar"; // 输出15
}
addit();
如上,如果声明时去掉global关键字,相当于没有赋值的局部变量,隐式地被初始化为0。
另一种使用全局变量的方法是使用$GLOBALS数组:
$somevar = 15;
function addit() {
$GLOBALS["somevar"]++;
echo "$somevar";
}
addit(); // 输出16
4.静态变量:在函数退出时不会丢失值,再次调用函数时还可继续使用该值:
function keep_track() {
static $count = 0;
$count++;
echo "$count\n";
}
keep_track(); // 输出1
keep_track(); // 输出2
keep_track(); // 输出3
它对于递归函数来说很有用。
php提供了很多预定义变量,包含在9个预定义数组中,可在执行脚本的任何位置访问,提供了与用户当前会话、操作系统、本地操作环境等有关的信息。而php会创建部分变量,变量的可用性和值取决于操作系统和Web服务器:
foreach ($_SERVER as $var => $value) {
echo "$var => $value\n";
} // 仅输出部分预定义变量
$_SERVER中包含很多有用的信息,如’REMOTE_ADDR’表示用户ip,'HTTP_USER_AGENT’表示用户的浏览器和操作系统信息。而我测试时由于使用的是命令行方式执行,所以没有这两个变量。
使用预定义数组必须先在php.ini中启用track_vars,PHP 4.03中,它总是启用的。
各个预定义变量数组,它们都是超级全局变量:
1.$_SERVER
:包含由Web服务器创建的信息,提供了服务器和客户配置及当前请求环境的有关信息。其中的变量数量不固定,一般可找到CGI 1.1(www.w3.org/CGI)规范中定义的变量,包括:
(1)'HTTP_REGERER'
:引导用户到达当前位置的页面的URL。
(2)'REMOTE_ADDR'
:客户ip地址。
(3)'REQUEST_URI'
:URL的路径部分,当URL是http://www.a.com/dir1/dir2/index.html时,路径部分为/dir1/dir2/index.html。
(4)'HTTP_USER_AGENT'
:用户的操作系统、浏览器相关信息。
2.$_GET
:包含使用get方法传递的参数的有关信息,如请求http://www.a.com/index.html?cat=apache$id=157,相当于给_GET数组这样赋值:
$_GET['cat'] = apache;
$_GET['id'] = 1157;
3.$_POST
:包含用户用post方法传递的参数有关信息,如以下表单:
就可以通过目标脚本subscribe.php使用下面的POST变量:
与$_GET一样,默认,$_POST是访问POST变量的唯一方式。
4.$_COOKIE
:储存了通过HTTP cookie传递到脚本的信息,这些cookie一般是以前通过调用setcookie设置的,如通过此函数设置了一个名为"example"、值为"123"的cookie,就可以通过$_COOKIE['example']
访问对应值123
。
5.$_FILE
:包含通过POST方法向服务器上传的数据的有关信息,它是二维数组,第一个下标是表单的上传名,第二个下标是五个预定义下标之一:
(1)$_FILE['upload-name']['name']
:从客户端向服务器上传的文件名。
(2)$_FILE['upload-name']['type']
:上传文件的MIME类型,该变量是否被赋值取决于浏览器功能。
(3)$_FILE['upload-name']['size']
:文件大小,以字节为单位。
(4)$_FILE['upload-name']['tmp_name']
:上传后,将该文件移动到最终位置前的临时名。
(5)$_FILE['upload-name']['error']
:上传的状态码,它的取值如下:
①:UPLOAD_ERR_OK
:上传成功。
②:UPLOAD_ERR_INI_SIZE
:文件大小超出了upload_max_filesize指令的最大值。
③:UPLOAD_ERR_FORM_SIZE
:文件大小超出了MAX_FILE_SIZE隐藏表单域参数(可选)指定的最大值。
④:UPLOAD_ERR_PARTIAL
:文件只上传了一部分。
⑤:UPLOAD_ERR_NO_FILE
:表单中没有上传文件。
6.$_ENV
:提供服务器的环境信息,如:
1.'HOST_NAME'
:服务器主机名。
2.'SHELL'
:系统SHELL。
php还支持$GLOBALS
和$_REQUEST
超级全局变量。$_REQUEST
记录get、post、cookie等方法传递给脚本的全部变量,这些变量的顺序不依赖于他们在发送脚本中出现的顺序,而是依赖于variables_order配置指令指定的顺序;$GLOBALS
可认为是超级全局变量的超集,它还包含全局作用域内的全部变量。最好不要使用这两个超级全局变量,这样不安全。
7._SESSION
:包含与会话有关的信息,注册会话信息可在整个网站中引用这些信息而无需通过get或post显式传递信息。
$recipe = "spaghetti";
$$recipe = "& meatballs"; // 将串赋值给名为spaghetti的变量
echo "$recipe $spaghetti"; // 输出spaghetti& meatballs
echo "$recipe $$recipe"; // 同上
常量是程序执行中无法修改的值,可使用define函数定义:
第三个参数为true时,后面对此常量的引用将不分大小写,默认情况下常量的引用区分大小写(与变量一样,都区分大小写)。
define("PI", 3.141592);
printf("The value of pi is %f" . PHP_EOL, PI); // 常量使用时不需要美元符
$pi = 2 * PI;
printf("pi doubled is %f", $pi);
一旦定义了常量就不能重新定义或取消定义。常量是全局的,可在脚本任何位置引用。
php中XOR表示布尔异或。
双引号括起的字符串中的变量和转义序列(如\n换行)都会得到相应的解析。
<?php
$output = "a\nb";
echo $output;
以上代码的换行会被浏览器窗口忽略,但如果查看源代码,会发现它是两行输出,将数据输出到文本文件或控制台也是分两行。
单引号括起来的字符串不会解析其变量和转义序列,但单引号可以被转义。反斜线也可以被转义,因为反斜线可以当作转义符使用,也可以当作普通字符使用。
在串中嵌入表示复杂类型的变量时,不太容易看出来哪些串的哪些部分是静态的,哪些是动态的,可通过大括号界定变量:
$arr = [1,2,3];
print("a s{$arr[1]}s"); // 输出a s2s
print("a s$arr[1]s"); // 同上
heredoc语法在输出大量文本时比较好用,它用两个相同标识符界定字符串:
print(<<<text
aaaaaa
bbbbbb
cccccc
text
);
开始和结束标识符必须相同,此例中是text。开始标识符前需要三个左尖括号。其中的所有变量和转义序列都得到解析,但其中的双引号不需转义。结束标识符必须在一行的开始处,且前面不能有空格或多余的字符,开始标识符同一行的后面也不能有空格或多余字符。
处理大量内容,或希望不转义引号时可用heredoc。
$arr = <<<text
"aaaaaa"
bbbbb
cccccc
text;
$s = (string)$arr; // 将它转换为字符串类型时,引号依然正常
var_dump($arr);
var_dump($s);
运行它:
nowdoc类似于heredoc,但它不会解析其中的变量,也不会转义其中的特殊字符,它的语法与heredoc唯一的不同是将heredoc的开始标识符加上单引号。nowdoc是php 5.3.0中引入的。
php的if、while、for、foreach、switch有另一种语法,即将前大括号改为冒号,后大括号改为endif、endwhile、endfor、endforeach、endswitch,但这种写法已经计划在未来的版本中弃用。
php中elseif
和else if
都能用。
switch可看作ifelse组合的一种变体,常用于将某变量与大量的值对比,其中的break规则与C++中相同。
switch在比较浮点型时,也会出现问题:
$a = 0.2;
switch($a + 0.1) {
case 0.3:
print(0.3); // 不被输出
break;
}
php中的switch的类型无限制。
foreach可提取数组中每个键值对,直到获得所有项,其语法有两种形式:
foreach (array_expr as $value) { // 只获取值
statement
}
foreach (array_expr as $key => $value) { // 获取键值对
statement
}
foreach中对数组的改变:
$arr = [1 => "a"];
foreach($arr as $key => $value) {
$value = "b"; // 不会改变,除非value是引用
}
print_r($arr);
foreach($arr as $key => $value) {
$arr[$key] = "b"; // 直接改变数组内容,值会被改变
}
print_r($arr);
foreach($arr as $key => $value) {
unset($arr[$key]); // 直接改变数组内容,值会被改变
}
print_r($arr);
运行它:
使用goto:
<?php
for($count = 0; $count < 10; ++$count) {
$randomNumber = rand(1,50);
if ($randomNumber < 10) {
goto less;
}
}
less:
echo "Number less than 10: $randomNumber";
include语句将在其被调用的位置判断并包含一个文件(其中可以含一系列预定义的函数和配置变量,此时一般将该文件include到php脚本顶部),效果相当于将该文件内容复制到该语句所在位置:
include("/path/to/filename");
include "/path/to/filename"; // 相当于上一句
如果include出现在if等条件语句后,则需要将其用花括号括起来:
<?php
if (expression) {
include('filename'); // 必须有花括号
}
但我测试时(php 7)不加花括号也行。
在被include的文件中也要有php定界符。
被include的文件中的所有代码会继承其调用位置处的变量作用域。
如果启用了allow_url_fopen,还可在include语句中引用一个远程文件。如果文件所在服务器支持php,可传递键值对,类似于get请求的做法,所包含文件中此键值对也会得到解析:
include_once作用与inclde相同,但它会首先验证是否已经包含了该文件,如果已经包含了,则不会再次执行包含文件操作:
include_once("文件路径");
require与include相似,书上说require即使放在if语句为假的部分也能包含指定文件,但我测试时(php 7)判断为假的if语句中是不能包含该文件的。
与include相同,只有启用allow_url_open时,才能在require中使用url。
require在出错时,脚本将停止运行,而include出错时,脚本将继续运行。常见的错误是引用的路径错误。
require_once确保脚本只被包含一次。有时修改了所包含文件中的变量后,会由于再次包含原来的文件而覆盖被修改的变量;重复包含文件会使其中的函数名产生冲突。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)