PHP进阶语法详解:命名空间、类型转换与文件操作

掌握了PHP面向对象编程的基础后,就可以深入学习命名空间、类型转换、文档注释、序列化以及文件操作等重要概念。

1、命名空间(Namespace)

命名空间是PHP 5.3引入的重要特性,它解决了类名、函数名和常量名冲突的问题,使得大型项目的代码组织更加清晰。

命名空间的基本使用

php 复制代码
<?php
// 定义命名空间
namespace App;

class User {
    public $name = "基础用户";
}

// 子命名空间
namespace App\Model;

class User {
    public $name = "模型用户";
}

// 更深层的命名空间
namespace App\Model\Database;

class Connection {
    public function connect() {
        echo "数据库连接成功";
    }
}

// 在同一个文件中定义多个命名空间
namespace App\Controller {
    class UserController {
        public function index() {
            echo "用户控制器";
        }
    }
}

namespace App\Service {
    class UserService {
        public function getUsers() {
            return ["用户1", "用户2"];
        }
    }
}
?>

命名空间的访问方式

php 复制代码
<?php
namespace App\Model;

class User {
    public $name = "用户模型";
}

function getUserInfo() {
    return "获取用户信息";
}

const VERSION = "1.0.0";

// 在其他文件中使用命名空间
namespace App\Controller;

// 1. 完全限定名称(从根命名空间开始)
$user1 = new \App\Model\User();

// 2. 限定名称(相对于当前命名空间)
// 假设当前在 App\Controller 命名空间中
$user2 = new \App\Model\User(); // 必须使用完全限定名

// 3. 非限定名称(不包含命名空间分隔符)
// 只能访问当前命名空间中的类
class HomeController {
    // 这个类在 App\Controller 命名空间中
}

$controller = new HomeController(); // 非限定名称
?>

use关键字和别名

php 复制代码
<?php
namespace App\Controller;

// 引入其他命名空间的类
use App\Model\User;
use App\Service\UserService;
use App\Model\Database\Connection;

// 使用别名避免冲突
use App\Model\User as ModelUser;
use App\Entity\User as EntityUser;

// 引入函数和常量
use function App\Helper\formatDate;
use const App\Config\DATABASE_HOST;

class UserController {
    public function index() {
        // 直接使用类名(已经通过use引入)
        $user = new User();
        
        // 使用别名
        $modelUser = new ModelUser();
        $entityUser = new EntityUser();
        
        // 使用引入的函数和常量
        echo formatDate(time());
        echo DATABASE_HOST;
    }
}

// 批量引入
use App\Model\{User, Product, Order};
use App\Service\{UserService, ProductService, OrderService};
?>

魔术常量和自动加载

php 复制代码
<?php
namespace App\Model;

class User {
    public function getNamespaceInfo() {
        echo "当前命名空间: " . __NAMESPACE__ . "\n";
        echo "当前类: " . __CLASS__ . "\n";
        echo "当前方法: " . __METHOD__ . "\n";
    }
}

// 手动加载类文件
if (!class_exists('App\Model\Product')) {
    require_once 'Product.php';
}

// 自动加载机制
spl_autoload_register(function ($className) {
    // 将命名空间转换为文件路径
    $file = str_replace('\\', '/', $className) . '.php';
    
    if (file_exists($file)) {
        require_once $file;
    }
});

// 现在可以直接使用类,无需手动引入
$user = new App\Model\User();
?>

Composer自动加载

现代PHP项目通常使用Composer来管理依赖和自动加载:

bash 复制代码
# 初始化Composer项目
composer init

# 在composer.json中配置PSR-4自动加载
{
    "autoload": {
        "psr-4": {
            "App\\": "src/",
            "Tests\\": "tests/"
        }
    }
}

# 更新自动加载
composer dump-autoload
<?php
// 引入Composer自动加载
require_once 'vendor/autoload.php';

// 现在可以直接使用所有通过Composer管理的类
use App\Model\User;
use App\Service\UserService;

$user = new User();
$service = new UserService();
?>

2、类型转换

PHP是弱类型语言,但有时需要强制转换数据类型。理解类型转换对于编写健壮的代码非常重要。

转换为字符串

php 复制代码
<?php
// 方法1:使用strval()函数
$number = 123;
$float = 3.14;
$bool = true;

$str1 = strval($number);    // "123"
$str2 = strval($float);     // "3.14"
$str3 = strval($bool);      // "1"

// 方法2:强制类型转换
$str4 = (string) $number;   // "123"
$str5 = (string) $bool;     // "1"

// 方法3:字符串连接
$str6 = $number . "";       // "123"
$str7 = $bool . "";         // "1"

// 布尔值转字符串的特殊情况
$trueStr = (string) true;   // "1"
$falseStr = (string) false; // ""(空字符串)

echo "数字转字符串: '$str1'\n";
echo "布尔true转字符串: '$str3'\n";
echo "布尔false转字符串: '$falseStr'\n";
?>

转换为整数

php 复制代码
<?php
// 方法1:使用intval()函数
$str = "123";
$float = 3.14;
$bool = true;

$int1 = intval($str);       // 123
$int2 = intval($float);     // 3(截断小数部分)
$int3 = intval($bool);      // 1

// 方法2:强制类型转换
$int4 = (int) $str;         // 123
$int5 = (integer) $float;   // 3

// 特殊情况处理
$mixedStr = "123abc";
$int6 = intval($mixedStr);  // 123(从开头解析数字)

$invalidStr = "abc123";
$int7 = intval($invalidStr); // 0(无法解析)

echo "字符串'123'转整数: $int1\n";
echo "浮点数3.14转整数: $int2\n";
echo "混合字符串'123abc'转整数: $int6\n";
echo "无效字符串'abc123'转整数: $int7\n";
?>

转换为浮点数

php 复制代码
<?php
// 方法1:使用floatval()函数
$str = "3.14";
$int = 123;

$float1 = floatval($str);   // 3.14
$float2 = floatval($int);   // 123.0

// 方法2:强制类型转换
$float3 = (float) $str;     // 3.14
$float4 = (double) $int;    // 123.0

// 科学计数法
$scientific = "1.23e4";     // 12300
$float5 = floatval($scientific);

echo "字符串'3.14'转浮点数: $float1\n";
echo "整数123转浮点数: $float2\n";
echo "科学计数法'1.23e4'转浮点数: $float5\n";
?>

转换为布尔值

php 复制代码
<?php
// 方法1:使用boolval()函数(PHP 5.5+)
$int = 0;
$str = "";
$array = [];

$bool1 = boolval($int);     // false
$bool2 = boolval($str);     // false
$bool3 = boolval($array);   // false

// 方法2:强制类型转换
$bool4 = (bool) $int;       // false
$bool5 = (boolean) $str;    // false

// 假值(转换为false的值)
$falseValues = [
    0,              // 整数0
    0.0,            // 浮点数0.0
    "",             // 空字符串
    "0",            // 字符串"0"
    null,           // null值
    false,          // false本身
    []              // 空数组
];

foreach ($falseValues as $value) {
    $result = (bool) $value ? 'true' : 'false';
    echo gettype($value) . " 值转布尔: $result\n";
}

// 真值示例
$trueValues = [1, -1, "hello", [1, 2, 3], new stdClass()];
?>

3、PHPDoc 文档注释

PHPDoc是PHP代码文档化的标准,它使用特殊的注释格式来描述代码的功能、参数、返回值等信息。

基本PHPDoc语法

php 复制代码
<?php
/**
 * 用户管理类
 * 
 * 提供用户的增删改查等基本操作
 * 
 * @author 张三 <zhangsan@example.com>
 * @version 1.0.0
 * @since 2024-01-01
 * @package App\Model
 */
class UserManager {
    
    /**
     * 用户数据
     * 
     * @var array
     */
    private $users = [];
    
    /**
     * 数据库连接对象
     * 
     * @var PDO|null
     */
    private $connection;
    
    /**
     * 构造函数
     * 
     * @param PDO $connection 数据库连接对象
     * @throws InvalidArgumentException 当连接对象无效时抛出
     */
    public function __construct(PDO $connection) {
        if (!$connection) {
            throw new InvalidArgumentException('数据库连接不能为空');
        }
        $this->connection = $connection;
    }
    
    /**
     * 创建新用户
     * 
     * @param string $name 用户姓名
     * @param string $email 用户邮箱
     * @param int $age 用户年龄
     * @return int 返回新创建用户的ID
     * @throws PDOException 数据库操作失败时抛出
     * @throws InvalidArgumentException 参数验证失败时抛出
     * 
     * @example
     * $userManager = new UserManager($pdo);
     * $userId = $userManager->createUser('张三', 'zhangsan@example.com', 25);
     */
    public function createUser(string $name, string $email, int $age): int {
        // 实现代码...
        return 1;
    }
    
    /**
     * 根据ID获取用户信息
     * 
     * @param int $id 用户ID
     * @return array|null 用户信息数组,不存在时返回null
     * 
     * @deprecated 1.2.0 使用getUserById()方法替代
     * @see getUserById()
     */
    public function getUser(int $id): ?array {
        // 实现代码...
        return null;
    }
    
    /**
     * 批量获取用户
     * 
     * @param array $ids 用户ID数组
     * @return array 用户信息数组
     * 
     * @todo 添加缓存机制提高性能
     * @link https://example.com/docs/user-api 相关API文档
     */
    public function getUsers(array $ids): array {
        // 实现代码...
        return [];
    }
}
?>

常用PHPDoc标签

php 复制代码
<?php
/**
 * 计算工具类
 * 
 * @package App\Utils
 * @author 李四 <lisi@example.com>
 * @copyright 2024 My Company
 * @license MIT License
 * @version 2.1.0
 */
class Calculator {
    
    /**
     * 计算两个数的和
     * 
     * @param int|float $a 第一个数
     * @param int|float $b 第二个数
     * @return int|float 两数之和
     * 
     * @example
     * $calc = new Calculator();
     * $result = $calc->add(10, 20); // 返回 30
     */
    public function add($a, $b) {
        return $a + $b;
    }
    
    /**
     * 计算数组平均值
     * 
     * @param array<int|float> $numbers 数字数组
     * @return float 平均值
     * @throws InvalidArgumentException 当数组为空时
     * 
     * @since 2.0.0
     */
    public function average(array $numbers): float {
        if (empty($numbers)) {
            throw new InvalidArgumentException('数组不能为空');
        }
        return array_sum($numbers) / count($numbers);
    }
}
?>

4、值传递与引用传递

理解PHP中参数传递的机制对于编写高效代码非常重要。

值传递(默认方式)

php 复制代码
<?php
/**
 * 值传递示例
 * 
 * @param int $number 传入的数值
 */
function incrementByValue(int $number): void {
    $number += 10;
    echo "函数内部: $number\n";
}

$originalNumber = 5;
echo "调用前: $originalNumber\n";  // 5

incrementByValue($originalNumber);   // 函数内部: 15

echo "调用后: $originalNumber\n";  // 5(原始值未改变)

// 对象的值传递(特殊情况)
class Counter {
    public $count = 0;
    
    public function increment() {
        $this->count++;
    }
}

function modifyObject(Counter $counter): void {
    $counter->increment();
    echo "函数内部count: {$counter->count}\n";
}

$myCounter = new Counter();
echo "调用前count: {$myCounter->count}\n";  // 0

modifyObject($myCounter);                    // 函数内部count: 1

echo "调用后count: {$myCounter->count}\n";  // 1(对象内容被修改了!)
?>

引用传递

php 复制代码
<?php
/**
 * 引用传递示例
 * 
 * @param int &$number 通过引用传递的数值
 */
function incrementByReference(int &$number): void {
    $number += 10;
    echo "函数内部: $number\n";
}

$originalNumber = 5;
echo "调用前: $originalNumber\n";      // 5

incrementByReference($originalNumber);  // 函数内部: 15

echo "调用后: $originalNumber\n";      // 15(原始值被修改了)

// 数组的引用传递
function addElement(array &$arr, $element): void {
    $arr[] = $element;
}

$fruits = ['苹果', '香蕉'];
echo "添加前: " . implode(', ', $fruits) . "\n";

addElement($fruits, '橙子');

echo "添加后: " . implode(', ', $fruits) . "\n";  // 苹果, 香蕉, 橙子

// 实际应用:交换两个变量的值
function swap(&$a, &$b): void {
    $temp = $a;
    $a = $b;
    $b = $temp;
}

$x = 10;
$y = 20;
echo "交换前: x=$x, y=$y\n";

swap($x, $y);

echo "交换后: x=$x, y=$y\n";  // x=20, y=10
?>

5、序列化

序列化是将PHP变量转换为可存储或传输的字符串格式的过程。

基本序列化操作

php 复制代码
<?php
// 基本数据类型序列化
$data = [
    'name' => '张三',
    'age' => 25,
    'skills' => ['PHP', 'JavaScript', 'MySQL'],
    'active' => true
];

// 序列化
$serialized = serialize($data);
echo "序列化结果:\n$serialized\n\n";

// 反序列化
$unserialized = unserialize($serialized);
print_r($unserialized);

// JSON序列化(推荐用于数据交换)
$jsonString = json_encode($data, JSON_UNESCAPED_UNICODE);
echo "JSON序列化:\n$jsonString\n\n";

$jsonData = json_decode($jsonString, true);
print_r($jsonData);
?>

对象序列化

php 复制代码
<?php
class User {
    public $name;
    public $email;
    private $password;
    
    public function __construct($name, $email, $password) {
        $this->name = $name;
        $this->email = $email;
        $this->password = $password;
    }
    
    /**
     * 序列化时调用,控制哪些属性被序列化
     */
    public function __sleep(): array {
        return ['name', 'email']; // 不序列化password
    }
    
    /**
     * 反序列化时调用,进行必要的初始化
     */
    public function __wakeup(): void {
        // 可以在这里重新初始化一些属性
        echo "对象被反序列化了\n";
    }
    
    public function getInfo(): string {
        return "用户: {$this->name}, 邮箱: {$this->email}";
    }
}

$user = new User('李四', 'lisi@example.com', 'secret123');

// 序列化对象
$serializedUser = serialize($user);
echo "序列化用户对象:\n$serializedUser\n\n";

// 反序列化对象
$unserializedUser = unserialize($serializedUser);
echo $unserializedUser->getInfo() . "\n";

// 文件存储示例
file_put_contents('user.dat', serialize($user));
$loadedUser = unserialize(file_get_contents('user.dat'));
?>

6、List解构赋值

List是PHP中一种方便的数组解构赋值方式,可以快速将数组元素赋值给多个变量。

基本list使用

php 复制代码
<?php
// 基本用法
$userInfo = ['张三', 25, 'zhangsan@example.com'];

// 传统方式
$name = $userInfo[0];
$age = $userInfo[1];
$email = $userInfo[2];

// 使用list解构
list($name, $age, $email) = $userInfo;
echo "姓名: $name, 年龄: $age, 邮箱: $email\n";

// PHP 5.4+ 可以使用短语法
[$name, $age, $email] = $userInfo;

// 跳过某些元素
list($name, , $email) = $userInfo; // 跳过年龄
echo "姓名: $name, 邮箱: $email\n";

// 获取部分元素
list($name, $age) = $userInfo;
echo "姓名: $name, 年龄: $age\n";
?>

高级list用法

php 复制代码
<?php
// 嵌套数组解构
$data = [
    ['产品A', 100],
    ['产品B', 200],
    ['产品C', 150]
];

foreach ($data as list($product, $price)) {
    echo "产品: $product, 价格: ¥$price\n";
}

// 关联数组解构(PHP 7.1+)
$user = ['name' => '王五', 'age' => 30, 'city' => '北京'];

// 按键名解构
['name' => $userName, 'age' => $userAge] = $user;
echo "用户: $userName, 年龄: $userAge\n";

// 函数返回多个值
function getUserData() {
    return ['李六', 28, 'developer'];
}

list($name, $age, $job) = getUserData();
echo "姓名: $name, 年龄: $age, 职业: $job\n";

// 交换变量值
$a = 10;
$b = 20;
list($a, $b) = [$b, $a];
echo "交换后: a=$a, b=$b\n";

// 处理CSV数据
$csvData = "张三,25,工程师\n李四,30,设计师\n王五,28,产品经理";
$lines = explode("\n", $csvData);

foreach ($lines as $line) {
    list($name, $age, $position) = explode(",", $line);
    echo "员工: $name, 年龄: $age, 职位: $position\n";
}
?>

7、文件操作

文件操作是Web开发中的常见需求,PHP提供了丰富的文件处理函数。

文件信息获取

php 复制代码
<?php
$filename = 'example.txt';

// 创建测试文件
file_put_contents($filename, "这是一个测试文件\n第二行内容");

// 检查文件是否存在
if (file_exists($filename)) {
    echo "文件存在\n";
    
    // 获取文件信息
    echo "是否为文件: " . (is_file($filename) ? '是' : '否') . "\n";
    echo "是否为目录: " . (is_dir($filename) ? '是' : '否') . "\n";
    echo "文件大小: " . filesize($filename) . " 字节\n";
    echo "文件名: " . basename($filename) . "\n";
    echo "文件路径: " . dirname($filename) . "\n";
    echo "文件类型: " . filetype($filename) . "\n";
    echo "修改时间: " . date('Y-m-d H:i:s', filemtime($filename)) . "\n";
    echo "是否可读: " . (is_readable($filename) ? '是' : '否') . "\n";
    echo "是否可写: " . (is_writable($filename) ? '是' : '否') . "\n";
}

// 获取文件扩展名
$pathInfo = pathinfo($filename);
echo "文件信息:\n";
echo "目录: " . $pathInfo['dirname'] . "\n";
echo "文件名: " . $pathInfo['filename'] . "\n";
echo "扩展名: " . ($pathInfo['extension'] ?? '无') . "\n";
?>

文件读写操作

php 复制代码
<?php
$filename = 'data.txt';

// 写入文件(覆盖模式)
$content = "第一行数据\n第二行数据\n第三行数据";
$bytesWritten = file_put_contents($filename, $content);
echo "写入了 $bytesWritten 字节\n";

// 追加内容
$additionalContent = "\n第四行数据";
file_put_contents($filename, $additionalContent, FILE_APPEND);

// 读取整个文件
$fileContent = file_get_contents($filename);
echo "文件内容:\n$fileContent\n";

// 按行读取文件
$lines = file($filename, FILE_IGNORE_NEW_LINES);
echo "按行读取:\n";
foreach ($lines as $lineNumber => $lineContent) {
    echo "第" . ($lineNumber + 1) . "行: $lineContent\n";
}

// 使用文件句柄进行操作
$file = fopen($filename, 'r');
if ($file) {
    echo "\n逐行读取:\n";
    while (($line = fgets($file)) !== false) {
        echo "读取到: " . trim($line) . "\n";
    }
    fclose($file);
}

// 写入模式示例
$logFile = 'log.txt';
$log = fopen($logFile, 'a'); // 追加模式
if ($log) {
    $timestamp = date('Y-m-d H:i:s');
    fwrite($log, "[$timestamp] 系统启动\n");
    fwrite($log, "[$timestamp] 用户登录\n");
    fclose($log);
}
?>

文件操作实用函数

php 复制代码
<?php
// 文件复制
$sourceFile = 'original.txt';
$targetFile = 'copy.txt';

file_put_contents($sourceFile, "原始文件内容");

if (copy($sourceFile, $targetFile)) {
    echo "文件复制成功\n";
}

// 文件重命名/移动
$oldName = 'copy.txt';
$newName = 'renamed.txt';

if (rename($oldName, $newName)) {
    echo "文件重命名成功\n";
}

// 删除文件
if (unlink($newName)) {
    echo "文件删除成功\n";
}

// 目录操作
$dirName = 'test_directory';

// 创建目录
if (mkdir($dirName, 0755)) {
    echo "目录创建成功\n";
}

// 创建多级目录
$nestedDir = 'parent/child/grandchild';
if (mkdir($nestedDir, 0755, true)) { // 第三个参数为true表示递归创建
    echo "多级目录创建成功\n";
}

// 列出目录内容
$files = scandir('.');
echo "当前目录文件:\n";
foreach ($files as $file) {
    if ($file != '.' && $file != '..') {
        echo "- $file\n";
    }
}

// 删除目录(只能删除空目录)
if (rmdir($dirName)) {
    echo "目录删除成功\n";
}

// 递归删除目录函数
function deleteDirectory($dir) {
    if (!is_dir($dir)) {
        return false;
    }
    
    $files = scandir($dir);
    foreach ($files as $file) {
        if ($file != '.' && $file != '..') {
            $filePath = $dir . '/' . $file;
            if (is_dir($filePath)) {
                deleteDirectory($filePath); // 递归删除子目录
            } else {
                unlink($filePath); // 删除文件
            }
        }
    }
    
    return rmdir($dir); // 删除空目录
}

// 使用递归删除函数
if (deleteDirectory('parent')) {
    echo "递归删除目录成功\n";
}
?>

文件上传处理

php 复制代码
<?php
// 处理文件上传
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['upload'])) {
    $uploadFile = $_FILES['upload'];
    
    // 检查上传是否成功
    if ($uploadFile['error'] === UPLOAD_ERR_OK) {
        $tmpName = $uploadFile['tmp_name'];
        $originalName = $uploadFile['name'];
        $fileSize = $uploadFile['size'];
        $fileType = $uploadFile['type'];
        
        // 安全检查
        $allowedTypes = ['image/jpeg', 'image/png', 'image/gif'];
        $maxSize = 2 * 1024 * 1024; // 2MB
        
        if (!in_array($fileType, $allowedTypes)) {
            echo "不允许的文件类型";
            exit;
        }
        
        if ($fileSize > $maxSize) {
            echo "文件太大";
            exit;
        }
        
        // 生成安全的文件名
        $extension = pathinfo($originalName, PATHINFO_EXTENSION);
        $safeName = uniqid() . '.' . $extension;
        $uploadDir = 'uploads/';
        
        // 确保上传目录存在
        if (!is_dir($uploadDir)) {
            mkdir($uploadDir, 0755, true);
        }
        
        $targetPath = $uploadDir . $safeName;
        
        // 移动上传文件
        if (move_uploaded_file($tmpName, $targetPath)) {
            echo "文件上传成功: $targetPath";
        } else {
            echo "文件上传失败";
        }
    } else {
        echo "上传错误: " . $uploadFile['error'];
    }
}
?>

<!-- 文件上传表单示例 -->
<!DOCTYPE html>
<html>
<head>
    <title>文件上传</title>
</head>
<body>
    <form method="POST" enctype="multipart/form-data">
        <div>
            <label>选择文件:</label>
            <input type="file" name="upload" accept="image/*">
        </div>
        <div>
            <input type="submit" value="上传文件">
        </div>
    </form>
</body>
</html>

8、总结

本文全面介绍了PHP的进阶语法特性:

核心知识点回顾:

  1. 命名空间 :解决命名冲突,组织代码结构
    • 使用namespace定义命名空间
    • 通过use关键字引入和使用别名
    • 配合Composer实现自动加载
  2. 类型转换 :在弱类型语言中进行强制类型转换
    • 字符串、整数、浮点数、布尔值之间的转换
    • 理解转换规则和特殊情况
  3. PHPDoc文档注释 :标准化代码文档
    • 使用@param@return@throws等标签
    • 提高代码可读性和可维护性
  4. 参数传递 :值传递与引用传递的区别
    • 默认值传递不影响原变量
    • 引用传递可以修改原变量
    • 对象传递的特殊性
  5. 序列化 :数据持久化和传输
    • serialize()/unserialize()用于PHP内部
    • json_encode()/json_decode()用于跨语言交换
  6. List解构赋值 :快速分解数组
    • 简化数组元素赋值
    • 支持嵌套和关联数组解构
  7. 文件操作 :文件和目录的完整操作
    • 文件信息获取和检查
    • 读写操作和权限管理
    • 目录创建和遍历

实践建议:

  1. 合理使用命名空间组织大型项目
  2. 重视代码文档,使用PHPDoc标准
  3. 注意内存使用,处理大文件时使用生成器
  4. 文件操作时考虑并发和异常处理
  5. 选择合适的序列化方式
  6. 优化文件I/O操作,减少磁盘访问
相关推荐
ServBay17 小时前
垃圾堆里编码?真的不要怪 PHP 不行
后端·php
用户9623779544820 小时前
CTF 伪协议
php
BingoGo3 天前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php
JaguarJack3 天前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php·服务端
BingoGo4 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php
JaguarJack4 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php·服务端
JaguarJack5 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
后端·php·服务端
BingoGo5 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
php
JaguarJack6 天前
告别 Laravel 缓慢的 Blade!Livewire Blaze 来了,为你的 Laravel 性能提速
后端·php·laravel
郑州光合科技余经理7 天前
代码展示:PHP搭建海外版外卖系统源码解析
java·开发语言·前端·后端·系统架构·uni-app·php