PHP面试里,手写代码是绕不过去的环节。不管你是刚入行还是干了几年,基础程序题的逻辑清晰度、写法习惯、边界处理,面试官一眼就能看出水平。下面这20道题基本都是高频出现的,我按类型拆分,每道题不光给代码,还会说说常见坑点和我的习惯写法。
一、数字运算类
1. 各位数字之和
核心逻辑:循环取出每一位数字,累加。
<?php
function sumOfDigits($num) {
$sum = 0;
while ($num > 0) {
$sum += $num % 10; // 取末位
$num = floor($num / 10); // 去掉末位
}
return $sum;
}
echo sumOfDigits(624); // 12
?>
个人见解:有些人喜欢用字符串拆分 str_split(),性能差别不大,但纯数学方法更符合“数字处理”的原意。面试官有时会追问“负数怎么处理”,建议先取绝对值。
2. 判断奇数偶数
核心逻辑:取模运算 %。
<?php
function checkEvenOdd($num) {
return ($num % 2 == 0) ? "偶数" : "奇数";
}
echo checkEvenOdd(23); // 奇数
?>
知识要点:注意浮点数或非数字输入的情况,项目开发中先用 is_numeric() 校验。
3. 素数判断
核心逻辑:从2到平方根之间,只要有一个能整除就不是素数。
<?php
function isPrime($num) {
if ($num < 2) return false;
for ($i = 2; $i <= sqrt($num); $i++) {
if ($num % $i == 0) return false;
}
return true;
}
var_dump(isPrime(17)); // true
var_dump(isPrime(57)); // false
?>
经验:很多人只循环到 $num/2,其实 sqrt($num) 效率更高。另外1和0要单独处理。
4. 打印乘法表(某一数的倍数)
<?php
function printTable($num) {
for ($i = 1; $i <= 10; $i++) {
echo $num * $i . " ";
}
}
printTable(5); // 5 10 15 20 25 30 35 40 45 50
?>
5. 阶乘计算
<?php
function factorial($n) {
$result = 1;
for ($i = 2; $i <= $n; $i++) {
$result *= $i;
}
return $result;
}
echo factorial(6); // 720
?>
注意:大数阶乘(比如50以上)会溢出,PHP可以用 gmp_strval(gmp_fact($n)) 扩展处理。面试题一般给小数字,循环写法够用。
6. 阿姆斯特朗数(自幂数)
定义:各位数字的立方和等于自身(三位数情况)。
<?php
function isArmstrong($num) {
$digits = str_split($num);
$sum = 0;
foreach ($digits as $digit) {
$sum += pow($digit, 3);
}
return $sum == $num;
}
var_dump(isArmstrong(371)); // true
?>
扩展:更高位数要用 strlen() 判断次方数,不限于3次方。
二、字符串与回文类
7. 回文数判断
<?php
function isPalindromeNumber($num) {
$original = $num;
$reverse = 0;
while ($num > 0) {
$reverse = $reverse * 10 + ($num % 10);
$num = floor($num / 10);
}
return $original == $reverse;
}
var_dump(isPalindromeNumber(121)); // true
?>
为什么不用字符串反转 strrev()?因为用数字反转更能体现底层逻辑,面试时多一层印象分。实际项目中我会用 strrev($num) 更简洁。
8. 反转字符串
<?php
function reverseString($str) {
$len = strlen($str);
$rev = '';
for ($i = $len - 1; $i >= 0; $i--) {
$rev .= $str[$i];
}
return $rev;
}
echo reverseString("amit"); // tima
?>
三、数组与数列类
9. 斐波那契数列(两种方式)
非递归(推荐):
<?php
function fibonacci($n) {
$a = 0;
$b = 1;
for ($i = 0; $i < $n; $i++) {
echo $a . " ";
$next = $a + $b;
$a = $b;
$b = $next;
}
}
fibonacci(10); // 0 1 1 2 3 5 8 13 21 34
?>
递归方式(理解用,生产慎用):
<?php
function fibRecursive($n) {
if ($n <= 1) return $n;
return fibRecursive($n - 1) + fibRecursive($n - 2);
}
for ($i = 0; $i < 10; $i++) {
echo fibRecursive($i) . " ";
}
?>
个人建议:递归写法到40项左右就很慢了,面试时记得提一下性能问题,显得有经验。
10. 反转数字
<?php
function reverseInteger($num) {
$rev = 0;
while ($num > 0) {
$rev = $rev * 10 + ($num % 10);
$num = intdiv($num, 10);
}
return $rev;
}
echo reverseInteger(234); // 432
?>
四、变量交换类
11. 交换两个数(两种方法)
方法一:借助第三个变量
$a = 5; $b = 10;
$temp = $a;
$a = $b;
$b = $temp;
方法二:不借助第三个变量(加减法)
$a = 5; $b = 10;
$a = $a + $b; // 15
$b = $a - $b; // 5
$a = $a - $b; // 10
注意:加减有溢出风险(大数相加超范围),也可以使用 list($a, $b) = [$b, $a],PHP自带这种写法安全。
五、几何计算类
12. 三角形面积
<?php
function area($base, $height) {
return ($base * $height) / 2;
}
echo area(10, 15); // 75
?>
13. 矩形面积
<?php
function areaRectangle($length, $width) {
return $length * $width;
}
echo areaRectangle(10, 20); // 200
?>
六、条件判断类
14. 闰年判断
规则:能被4整除但不能被100整除,或者能被400整除。
<?php
function isLeapYear($year) {
return ($year % 4 == 0 && $year % 100 != 0) || ($year % 400 == 0);
}
var_dump(isLeapYear(2000)); // true
var_dump(isLeapYear(2001)); // false
?>
七、图形打印类(面试常考,但不一定手写完整,看思路)
15. 字母三角形
输出:
A
ABA
ABCBA
ABCDCBA
代码思路(核心部分):
<?php
$n = 5;
for ($i = 1; $i <= $n; $i++) {
// 上升部分 A B C...
for ($j = 0; $j < $i; $j++) {
echo chr(65 + $j);
}
// 下降部分 B A
for ($j = $i - 2; $j >= 0; $j--) {
echo chr(65 + $j);
}
echo "\n";
}
?>
16. 数字三角形
输出(range=6时):
1
121
12321
核心:对称输出,左边递增,右边递减。
<?php
$range = 6;
for ($i = 1; $i <= $range; $i++) {
for ($j = 1; $j <= $i; $j++) {
echo $j;
}
for ($j = $i - 1; $j >= 1; $j--) {
echo $j;
}
echo "\n";
}
?>
17. 星号三角形(四种常见形态)
正立三角:
for ($i = 1; $i <= 5; $i++) {
echo str_repeat('*', $i) . "\n";
}
倒立三角:
for ($i = 5; $i >= 1; $i--) {
echo str_repeat('*', $i) . "\n";
}
等腰三角(带空格):
$n = 5;
for ($i = 1; $i <= $n; $i++) {
echo str_repeat(' ', $n - $i) . str_repeat('*', 2 * $i - 1) . "\n";
}
空心等腰:需要判断第一行、之后一行和每行首尾。
八、小提示
-
面试时写完代码,自己主动说边界情况(负数、0、超大数、非数字输入)会加分很多。
-
能不依赖内置函数就不依赖,展示算法思路,但之后可以补充一句“生产中我会用
strrev()/array_reverse()更高效”。 -
图形题不要求跑出结果,核心是对称逻辑写对就行。
以上代码全部在 PHP 7.4 / 8.x 环境下测试过。如果有不明白的地方,可以邮件联系 alan@ebingou.cn 交流。