1. PHP基础语法与核心概念
PHP作为一门动态类型的服务器端脚本语言,其基础语法是面试中最常考察的部分。以下是几个典型的基础语法考点:
1.1 变量与数据类型
PHP中的变量以$符号开头,不需要预先声明类型。常见数据类型包括:
- 标量类型:整型(int)、浮点型(float)、布尔型(bool)、字符串(string)
- 复合类型:数组(array)、对象(object)
- 特殊类型:资源(resource)、NULL
// 类型转换示例 $num = "123"; // 字符串 $num = (int)$num; // 显式转换为整型类型转换是面试常考点,特别是弱类型比较带来的问题。比如"123abc" == 123会返回true,而使用===严格比较则返回false。
1.2 运算符优先级
PHP运算符优先级经常出现在笔试题中,特别是以下容易混淆的情况:
$result = 1 + 2 * 3; // 结果是7而不是9 $result = true ? 0 : true ? 1 : 2; // 结果是1而不是0建议在复杂表达式中使用括号明确优先级,这既是良好编码习惯,也能避免面试中的陷阱题。
1.3 控制结构
PHP支持所有常见的控制结构,但有些细节需要注意:
// switch语句是松散比较 switch ("foo") { case 0: // 这里会匹配,因为"foo" == 0 echo "意外匹配"; break; } // foreach对数组的修改行为 $arr = [1, 2, 3]; foreach ($arr as &$val) { $val++; } // 此时$val仍然是对最后一个元素的引用 unset($val); // 必须手动解除引用2. 函数与面向对象编程
2.1 函数特性
PHP函数支持多种特性,常考的点包括:
- 可变函数:通过变量名调用函数
function foo() { echo "foo"; } $func = 'foo'; $func(); // 调用foo()- 匿名函数(闭包)
$greet = function($name) { return "Hello $name"; }; echo $greet("World");2.2 类与对象
面向对象是PHP面试的重点考察领域:
class MyClass { public $public = 'Public'; protected $protected = 'Protected'; private $private = 'Private'; public function printProperties() { echo $this->public; // 可访问 echo $this->protected; // 可访问 echo $this->private; // 可访问 } } $obj = new MyClass(); echo $obj->public; // 可访问 // echo $obj->protected; // 报错 // echo $obj->private; // 报错继承、接口、抽象类、trait等概念也是常考点:
trait Loggable { public function log($msg) { echo $msg; } } class User { use Loggable; } $user = new User(); $user->log("记录日志"); // 使用trait中的方法3. 数组与字符串操作
3.1 数组函数
PHP提供了丰富的数组函数,面试常考的有:
$arr = ['a' => 1, 'b' => 2, 'c' => 3]; // 数组合并 $arr2 = ['a' => 4, 'd' => 5]; $merged = array_merge($arr, $arr2); // a=>4, b=>2, c=>3, d=>5 // 数组过滤 $filtered = array_filter($arr, function($v) { return $v > 1; }); // 数组映射 $mapped = array_map(function($v) { return $v * 2; }, $arr);3.2 字符串处理
字符串操作也是PHP面试的重点:
// 字符串查找 $str = "Hello world"; $pos1 = strpos($str, "world"); // 6 $pos2 = stripos($str, "WORLD"); // 不区分大小写 // 字符串替换 $newStr = str_replace("world", "PHP", $str); // 正则表达式 if (preg_match('/\d+/', 'abc123', $matches)) { echo $matches[0]; // 123 }4. 文件系统与IO操作
4.1 文件读写
PHP文件操作是常见考点:
// 文件写入 file_put_contents('test.txt', 'Hello PHP'); // 文件读取 $content = file_get_contents('test.txt'); // 逐行读取 $handle = fopen('largefile.txt', 'r'); while (!feof($handle)) { $line = fgets($handle); // 处理每一行 } fclose($handle);4.2 目录操作
// 遍历目录 $dir = new DirectoryIterator('/path/to/dir'); foreach ($dir as $fileinfo) { if (!$fileinfo->isDot()) { echo $fileinfo->getFilename(); } } // 递归目录 $it = new RecursiveDirectoryIterator('/path'); $it = new RecursiveIteratorIterator($it); foreach ($it as $file) { echo $file->getPathname(); }5. 数据库操作
5.1 PDO基础
PDO是PHP推荐的数据库访问方式:
try { $pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass'); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // 预处理语句 $stmt = $pdo->prepare('SELECT * FROM users WHERE id = :id'); $stmt->execute([':id' => 1]); $user = $stmt->fetch(PDO::FETCH_ASSOC); // 事务处理 $pdo->beginTransaction(); // 执行多个SQL $pdo->commit(); } catch (PDOException $e) { $pdo->rollBack(); echo "Error: " . $e->getMessage(); }5.2 SQL注入防御
SQL注入是必考的安全问题:
// 错误做法 - 直接拼接SQL $id = $_GET['id']; $sql = "SELECT * FROM users WHERE id = $id"; // 危险! // 正确做法 - 使用预处理语句 $stmt = $pdo->prepare('SELECT * FROM users WHERE id = ?'); $stmt->execute([$id]);6. 会话管理与安全
6.1 Cookie和Session
// 设置Cookie setcookie('name', 'value', time()+3600, '/', 'example.com', true, true); // 使用Session session_start(); $_SESSION['user'] = ['id' => 1, 'name' => 'John'];6.2 安全防护
常见安全问题和防护措施:
// XSS防护 echo htmlspecialchars($userInput, ENT_QUOTES, 'UTF-8'); // CSRF防护 $token = bin2hex(random_bytes(32)); $_SESSION['csrf_token'] = $token; // 表单中包含这个token并验证 // 密码哈希 $password = 'userpassword'; $hash = password_hash($password, PASSWORD_DEFAULT); if (password_verify($password, $hash)) { // 密码正确 }7. 错误处理与调试
7.1 错误处理机制
// 自定义错误处理 set_error_handler(function($errno, $errstr, $errfile, $errline) { // 记录错误或发送通知 return true; // 阻止默认错误处理 }); // 异常处理 try { // 可能抛出异常的代码 } catch (Exception $e) { echo 'Caught exception: ', $e->getMessage(); } finally { // 无论是否异常都会执行 }7.2 调试技巧
// 调试输出 var_dump($variable); print_r($array); // 记录日志 error_log('Debug message', 3, '/path/to/logfile.log'); // Xdebug配置 // php.ini中配置xdebug扩展8. 性能优化
8.1 代码层面优化
// 避免在循环中做重复操作 for ($i = 0; $i < count($largeArray); $i++) { // 不好 - 每次循环都计算count // ... } $count = count($largeArray); // 好 - 预先计算 for ($i = 0; $i < $count; $i++) { // ... } // 使用isset()判断数组键存在比array_key_exists()更快 if (isset($array['key'])) { // ... }8.2 缓存策略
// 使用APCu缓存 apcu_add('cache_key', $data, 3600); $data = apcu_fetch('cache_key'); // 使用Memcached $memcached = new Memcached(); $memcached->addServer('localhost', 11211); $memcached->set('key', 'value', 3600); $value = $memcached->get('key');9. 常见设计模式
9.1 单例模式
class Database { private static $instance; private function __construct() {} public static function getInstance() { if (!self::$instance) { self::$instance = new self(); } return self::$instance; } private function __clone() {} private function __wakeup() {} } $db = Database::getInstance();9.2 工厂模式
interface Logger { public function log($message); } class FileLogger implements Logger { public function log($message) { file_put_contents('log.txt', $message, FILE_APPEND); } } class DatabaseLogger implements Logger { public function log($message) { // 记录到数据库 } } class LoggerFactory { public static function create($type) { switch ($type) { case 'file': return new FileLogger(); case 'database': return new DatabaseLogger(); default: throw new Exception("Unknown logger type"); } } } $logger = LoggerFactory::create('file'); $logger->log('Test message');10. PHP新特性
10.1 PHP 8.x新特性
// 命名参数(PHP 8.0) function foo($a, $b = null, $c = null) {} foo(c: 'value', a: 'test'); // 联合类型(PHP 8.0) function bar(int|string $input): int|float {} // 属性构造器(PHP 8.0) class User { public function __construct( public string $name, protected int $age, ) {} } // match表达式(PHP 8.0) $result = match ($statusCode) { 200, 300 => 'success', 400 => 'not found', default => 'unknown', }; // 只读属性(PHP 8.1) class Post { public readonly string $title; public function __construct(string $title) { $this->title = $title; } } // 枚举(PHP 8.1) enum Status: string { case Draft = 'draft'; case Published = 'published'; case Archived = 'archived'; }11. 框架相关概念
11.1 MVC架构
// 简单的MVC实现示例 class Model { protected $db; public function __construct(PDO $db) { $this->db = $db; } public function getUsers() { return $this->db->query('SELECT * FROM users')->fetchAll(); } } class View { public function render($template, $data = []) { extract($data); include "templates/$template.php"; } } class Controller { protected $model; protected $view; public function __construct(Model $model, View $view) { $this->model = $model; $this->view = $view; } public function index() { $users = $this->model->getUsers(); $this->view->render('users', ['users' => $users]); } }11.2 依赖注入
class Mailer { public function send($message) { // 发送邮件 } } class UserManager { private $mailer; public function __construct(Mailer $mailer) { $this->mailer = $mailer; } public function register($user) { // 注册用户 $this->mailer->send('Welcome!'); } } // 依赖注入容器简单实现 class Container { protected $instances = []; public function get($class) { if (!isset($this->instances[$class])) { $reflector = new ReflectionClass($class); $constructor = $reflector->getConstructor(); if (!$constructor) { return new $class; } $parameters = $constructor->getParameters(); $dependencies = []; foreach ($parameters as $parameter) { $dependency = $parameter->getClass(); $dependencies[] = $this->get($dependency->name); } $this->instances[$class] = $reflector->newInstanceArgs($dependencies); } return $this->instances[$class]; } } $container = new Container(); $userManager = $container->get('UserManager'); $userManager->register($userData);12. 测试与部署
12.1 单元测试
// PHPUnit测试示例 use PHPUnit\Framework\TestCase; class CalculatorTest extends TestCase { public function testAdd() { $calc = new Calculator(); $this->assertEquals(4, $calc->add(2, 2)); $this->assertEquals(0, $calc->add(0, 0)); $this->assertEquals(-1, $calc->add(1, -2)); } } class Calculator { public function add($a, $b) { return $a + $b; } }12.2 持续集成
# .github/workflows/ci.yml 示例 name: CI on: [push, pull_request] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Setup PHP uses: shivammathur/setup-php@v2 with: php-version: '8.1' extensions: mbstring, xml, curl, pdo, mysql coverage: xdebug - name: Install dependencies run: composer install --prefer-dist --no-progress --no-suggest - name: Run tests run: vendor/bin/phpunit13. 实际案例分析
13.1 用户登录系统
class Auth { private $pdo; private $session; public function __construct(PDO $pdo, SessionInterface $session) { $this->pdo = $pdo; $this->session = $session; } public function login($email, $password) { $stmt = $this->pdo->prepare('SELECT * FROM users WHERE email = ?'); $stmt->execute([$email]); $user = $stmt->fetch(); if ($user && password_verify($password, $user['password'])) { $this->session->set('user_id', $user['id']); return true; } return false; } public function logout() { $this->session->remove('user_id'); } public function isLoggedIn() { return $this->session->has('user_id'); } } interface SessionInterface { public function set($key, $value); public function get($key); public function has($key); public function remove($key); }13.2 API接口开发
header('Content-Type: application/json'); try { $pdo = new PDO('mysql:host=localhost;dbname=api', 'user', 'pass'); $method = $_SERVER['REQUEST_METHOD']; $path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); $pathParts = explode('/', trim($path, '/')); $resource = $pathParts[0] ?? null; $id = $pathParts[1] ?? null; if ($resource === 'users') { if ($method === 'GET') { if ($id) { $stmt = $pdo->prepare('SELECT * FROM users WHERE id = ?'); $stmt->execute([$id]); $user = $stmt->fetch(PDO::FETCH_ASSOC); if ($user) { echo json_encode($user); } else { http_response_code(404); echo json_encode(['error' => 'User not found']); } } else { $stmt = $pdo->query('SELECT * FROM users'); echo json_encode($stmt->fetchAll(PDO::FETCH_ASSOC)); } } elseif ($method === 'POST') { $input = json_decode(file_get_contents('php://input'), true); $stmt = $pdo->prepare('INSERT INTO users (name, email) VALUES (?, ?)'); $stmt->execute([$input['name'], $input['email']]); http_response_code(201); echo json_encode(['id' => $pdo->lastInsertId()]); } else { http_response_code(405); echo json_encode(['error' => 'Method not allowed']); } } else { http_response_code(404); echo json_encode(['error' => 'Resource not found']); } } catch (PDOException $e) { http_response_code(500); echo json_encode(['error' => 'Database error']); }14. 面试技巧与准备
14.1 常见面试问题
基础问题:
- PHP的生命周期
- 魔术方法有哪些
- 自动加载原理
- 命名空间的作用
算法题:
- 实现冒泡排序
- 反转链表
- 查找数组中的重复元素
设计题:
- 设计一个简单的MVC框架
- 设计一个缓存系统
- 设计一个用户权限系统
14.2 项目经验准备
准备2-3个有代表性的项目,能够清晰描述:
- 项目背景和你的角色
- 技术选型的原因
- 遇到的技术挑战和解决方案
- 项目的成果和你的贡献
14.3 编码规范
// 良好的编码习惯示例 declare(strict_types=1); // 严格类型模式 namespace App\Service; use App\Exception\InvalidUserException; use App\Repository\UserRepositoryInterface; class UserService { private UserRepositoryInterface $repository; public function __construct(UserRepositoryInterface $repository) { $this->repository = $repository; } public function registerUser( string $username, string $email, string $password ): int { if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { throw new InvalidUserException('Invalid email format'); } $hashedPassword = password_hash($password, PASSWORD_DEFAULT); return $this->repository->createUser( $username, $email, $hashedPassword ); } }