
资料在文章末尾
PHP 入门系列第二篇。环境搭好后,这一篇把变量、八种数据类型、运算符、字符串函数一次讲透,附完整可运行代码。
上一篇我们把 PHP 环境跑起来了,这一篇正式进语法。我第一次学 PHP 的时候,卡最久的不是什么高深概念,而是"0.1 + 0.2 为什么不等于 0.3"、"== 判断明明相等却不进 if"这种坑。所以这篇除了讲语法规则,我会在容易踩坑的地方单独标注。
整篇的内容顺序是:变量与常量 → 八种数据类型 → 类型转换 → 运算符 → 字符串函数。代码都可以直接复制运行,建议边看边敲。
变量就是用来存数据的容器,名字是标签,值是里面装的东西,随时可以换。PHP 里变量必须以 $ 开头。
变量名区分大小写,只能包含字母、数字、下划线,不能以数字开头。常用驼峰式或下划线式。
<?php// 合法命名$name = "张三";$_age = 25;$myFavoriteColor = "蓝色"; // 驼峰式$user_first_name = "李"; // 下划线式// 非法命名// $123abc = "error"; // 不能以数字开头// $my-var = "error"; // 不能包含连字符?>这是第一个容易踩坑的地方。默认是传值赋值——把值复制一份,两个变量互不影响:
<?php$a = 10;$b = $a; // $b 得到 $a 的副本$b = 20;echo $a; // 输出 10,$a 不受影响?>加 & 就是引用赋值,两个变量指向同一块内存,一改俱改:
<?php$a = 10;$b = &$a; // $b 是 $a 的别名$b = 20;echo $a; // 输出 20?>实战提醒:实际项目里引用赋值用得不多,一旦用错排查起来很痛苦。除非你明确需要"多个变量同步修改",否则用默认的传值赋值就好。
PHP 允许用一个变量的值作为另一个变量的名字,叫"变量的变量":
<?php$fruit = "apple";$$fruit = "红富士"; // 相当于 $apple = "红富士";echo $apple; // 输出 "红富士"?>灵活但可读性差,实际开发中极少用,知道有这东西就行。
常量一旦定义就不能改,适合存网站域名、数据库配置、数学常数这类固定值。
<?php// 方式一:define() 运行阶段定义define("SITE_NAME", "我的博客");define("MAX_LOGIN_ATTEMPTS", 5);// 方式二:const 关键字 编译阶段定义const DB_HOST = "localhost";const DB_USER = "root";echo SITE_NAME; // 常量名前不需要 $echo DB_HOST;?>两者区别:define 可以用在条件语句里,const 不行。一般业务代码用 define,类常量用 const。
PHP 预定义了一些常量,值会随所在位置变化,调试时很有用:
<?phpecho __LINE__; // 当前行号echo __FILE__; // 当前文件完整路径echo __DIR__; // 当前文件所在目录echo __FUNCTION__; // 当前函数名(在函数内)?>PHP 是弱类型语言,同一个变量可以先后存不同类型的值。但理解每种类型的特点很重要——很多 bug 就出在对类型理解不到位。
存不带小数的数字,支持十进制、八进制(0 开头)、十六进制(0x 开头)、二进制(0b 开头)。
<?php$decimal = 42; // 十进制$octal = 0755; // 八进制 等于十进制 493$hex = 0xFF; // 十六进制 等于十进制 255$binary = 0b1100; // 二进制 等于十进制 12echo PHP_INT_MAX; // 64位系统通常是 9223372036854775807?>超出整型范围会被自动转成浮点型。
带小数的数,或用科学计数法表示的大数。
<?php$price = 19.99;$distance = 3.4e3; // 3.4 × 10³ = 3400?>必踩的坑:浮点数在计算机里是二进制近似存储,0.1 + 0.2不等于0.3:
<?php$a = 0.1;$b = 0.2;$c = $a + $b;var_dump($c == 0.3); // bool(false)!// 实际 $c 是 0.30000000000000004// 正确做法:用误差范围比较if (abs($c - 0.3) < 0.00001) { echo "相等";}?>涉及金额计算的场景,用 bcmath 扩展(bcadd、bccomp 等),不要直接用浮点运算。
只有 true 和 false,不区分大小写,常用于条件判断。
关键要记住哪些值会被当成 false:
false 本身0、浮点型 0.0"" 和字符串 "0"[]NULL其余所有值都视为 true。这就是所谓的"松散比较"。
PHP 字符串有四种定义方式,区别主要在是否解析变量和转义字符处理。
单引号:不解析变量,只有 \\ 和 \' 两个转义有效。性能略好。
<?php$name = "小明";echo '你好,$name'; // 输出:你好,$name(变量没被解析)echo 'I\'m happy'; // 输出:I'm happy?>双引号:解析变量和转义字符(\n、\t 等)。
<?php$count = 5;echo "你有 $count 条新消息。"; // 输出:你有 5 条新消息。// 变量名后紧跟字母时,用花括号明确边界$fruit = "apple";echo "I like {$fruit}s."; // 输出:I like apples.?>Heredoc(<<<EOT):适合大段文本,会解析变量,类似双引号。结束标识符必须独占一行、不能有缩进。
<?php$title = "公告";$str = <<<EOT<h2>$title</h2><p>多行文本,支持变量解析。</p>EOT;echo $str;?>Nowdoc(<<<'EOT'):相当于加强版单引号,不解析变量。
数组是 PHP 里最常用的数据结构,下一篇会专门讲。这里先认识两种形式:
<?php// 索引数组(键为数字)$colors = ["红", "绿", "蓝"];echo $colors[0]; // "红"$colors[] = "黄"; // 追加到末尾// 关联数组(键为字符串)$user = [ "name" => "李四", "age" => 30, "city" => "上海"];echo $user["name"]; // "李四"?>通过 new 实例化类得到,面向对象编程的核心。
<?phpclass Person { public $name; public function sayHello() { echo "你好,我叫 $this->name"; }}$p = new Person();$p->name = "王五";$p->sayHello(); // 输出:你好,我叫王五?>NULL 表示变量没有值。被显式赋值为 NULL、尚未赋值、或被 unset() 销毁的变量都是 NULL。
Resource 是特殊类型,保存外部资源引用(文件句柄、数据库连接等):
<?php$file = fopen("test.txt", "r"); // 返回资源var_dump($file); // resource(...)fclose($file); // 用完要手动释放?>var_dump() 输出类型和值,是调试利器。gettype() 返回类型名字符串。is_* 系列函数判断具体类型:
<?php$val = "hello";is_string($val); // trueis_int($val); // falseis_numeric("123"); // true(数值字符串也算)isset($val); // true(变量存在且不为 NULL)empty($val); // false(空字符串、0、"0"、false、NULL、空数组时返回 true)?>面试常问:isset()判断变量是否存在且不为 NULL;empty()判断值是否为空。关键区别:empty()对不存在的变量也不会报警告。
自动转换:PHP 根据运算符上下文自动转。
<?php$num = "10" + 5; // "10" 转成整数 10,结果 15$str = "10" . 5; // 点运算符把 5 转成字符串,结果 "105"?>强制转换:在变量前加括号指定类型,不改原变量。
<?php$x = 3.14;$y = (int)$x; // $y = 3,$x 仍是 3.14$z = (string)$x; // $z = "3.14"// 函数转换echo intval("42px"); // 42?>常用转换关键字:(int)、(float)、(string)、(bool)、(array)、(object)。
+-*/% 取模、** 乘方(PHP 5.6+)。赋值运算符 = 可与算术运算符组合:+=、.= 等。
这是 PHP 里最重要的一个区别,也是出 bug 最多的地方:
==:会先做类型转换再比较值
===:要求类型和值都相等
<?phpvar_dump(0 == "0"); // true,字符串 "0" 转成整数 0var_dump(0 === "0"); // false,类型不同var_dump(0 == false); // true,false 转成 0var_dump(0 === false); // false// 太空船运算符 <=> 返回 -1/0/1echo 5 <=> 10; // -1echo 10 <=> 10; // 0echo 15 <=> 10; // 1?>实战建议:永远优先用===,只有在明确需要松散比较时才用==。这个习惯能帮你避开一大批诡异 bug。
&& 与、|| 或、! 非。注意 && 优先级高于 and,|| 高于 or,推荐统一用符号形式。
<?php$logged = true;$admin = false;if ($logged && $admin) { echo "进入管理面板";} else { echo "权限不足";}// 短路特性:左侧已能决定结果时,右侧不执行$result = false && someFunction(); // someFunction() 不会被调用?>点号 . 连接字符串,.= 连接并赋值。++-- 分前置后置,影响返回值。
<?php// 字符串连接$msg = "Hello";$msg .= " PHP"; // $msg = "Hello PHP"// 递增$a = 5;echo $a++; // 输出 5,然后 $a 变 6(后置:先返回旧值)echo ++$a; // $a 变 7,输出 7(前置:先自增再返回)// 三元运算符$age = 20;$status = ($age >= 18) ? "成年人" : "未成年人";// 空合并运算符 ??(PHP 7+)$name = $_GET['user'] ?? "游客"; // 不存在或为 NULL 时用默认值// 空合并赋值 ??=(PHP 7.4+)$count = null;$count ??= 10; // 等价于 $count = $count ?? 10;?>PHP 内置上百个字符串函数,这里列最常用的。
<?php// 长度echo strlen("hello"); // 5echo strlen("你好"); // 6(UTF-8 一个汉字 3 字节)echo mb_strlen("你好"); // 2(多字节安全,处理中文用这个)// 查找$text = "Hello World";$pos = strpos($text, "World"); // 返回 6(从 0 计)// 未找到返回 false// 替换$new = str_replace("Hello", "你好", $text);?>必踩的坑:strpos找到第一个字符时返回 0,而 0 在松散比较中等同于 false。判断是否找到必须用!== false:
<?php// 错误写法:如果 "Hello" 在开头,$pos=0,会被当成 falseif (strpos($text, "Hello") != false) { ... }// 正确写法if (strpos($text, "Hello") !== false) { echo "找到了";}?><?php$str = "abcdefg";echo substr($str, 0, 3); // "abc"echo substr($str, -3); // "efg"(负数从末尾算)echo substr($str, 3); // "defg"(取到末尾)// 字符串转数组$arr = explode(",", "苹果,香蕉,橘子");// ["苹果", "香蕉", "橘子"]// 数组转字符串echo implode(" | ", $arr); // "苹果 | 香蕉 | 橘子"?><?php// 大小写echo strtolower("HELLO"); // "hello"echo strtoupper("hello"); // "HELLO"echo ucfirst("hello"); // "Hello"// 去首尾空白echo trim(" 有空格 "); // "有空格"// 填充到指定长度echo str_pad("42", 5, "0", STR_PAD_LEFT); // "00042"// 防止 XSS:把特殊字符转成 HTML 实体$user_input = '<script>alert("XSS")</script>';echo htmlspecialchars($user_input); // 浏览器显示为文本,不执行脚本// 去除 HTML 标签echo strip_tags("<p>这是<b>粗体</b></p>"); // "这是粗体"?>把这篇的知识串起来,写一个动态生成用户卡片的脚本。这个例子覆盖了变量、类型转换、字符串函数、三元运算符:
<?php// 模拟用户数据$username = " 张三 ";$age = 28;$city = "北京";$hobbies = ["编程", "摄影", "旅行"];$bio = "热爱技术,喜欢用代码创造价值。";// 数据清洗$username = trim($username); // 去空格$safe_bio = htmlspecialchars($bio); // 防 XSS$user_status = ($age >= 18) ? "成年人" : "未成年人"; // 三元判断$hobby_text = implode("、", $hobbies); // 数组转字符串?><!DOCTYPE html><html lang="zh-CN"><head> <meta charset="UTF-8"> <title><?php echo $username; ?> 的个人卡片</title> <style> .card { border: 1px solid #ccc; padding: 20px; width: 300px; } .avatar { width: 100px; height: 100px; border-radius: 50%; background: #4299e1; color: white; font-size: 40px; display: flex; align-items: center; justify-content: center; } </style></head><body><div class="card"> <div class="avatar"><?php echo mb_substr($username, 0, 1); ?></div> <h2><?php echo $username; ?> (<?php echo $user_status; ?>)</h2> <p>城市:<?php echo $city; ?></p> <p>爱好:<?php echo $hobby_text; ?></p> <p>简介:<?php echo $safe_bio; ?></p></div></body></html>保存为 card.php 运行,就能看到一张用户卡片。试着把 $username 改成带 <script> 的内容,观察 htmlspecialchars 的防护效果。


$ 开头,默认传值赋值,引用赋值用&define() 或 const 定义,全局有效,值不可变is_* 系列判断类型,(int) 等强制转换=== 优先于 ==,?? 空合并简化默认值处理strpos 判断要用 !== false,处理中文用 mb_* 系列$a = 10; 和 $b = "10";,分别用 == 和 === 比较,用 var_dump() 输出结果并解释原因。$_GET['name'] 参数,用 ?? 设默认值"访客",输出"欢迎你,[名字]!",并用 htmlspecialchars 防止 XSS。"apple, banana, orange" 用 explode 分割成数组,再循环打印。PI = 3.14,半径 $r = 5,计算圆面积输出"半径为 5 的圆的面积是 78.5"。本文借助 AI 辅助整理,代码示例均已实测可运行。如有错误欢迎留言指出。
如果这篇文章帮你解决了实操上的困惑,别忘记点击点赞、分享,也可以留言告诉我你遇到的其它问题,我会尽快回复。动手练习是掌握编程最快的方法,请务必亲手敲一遍本文的所有示例代码,并截图保存你的成果。你的关注是我坚持原创和细节共享的力量来源,谢谢大家。

本文配套资料包
资料下载

-END-
