php数组如何创建和遍历_php创建数组与循环遍历教程

PHP数组可通过array()或[]创建,推荐用foreach遍历,索引数组用for时应缓存count值以优化性能。

php数组如何创建和遍历_php创建数组与循环遍历教程

PHP数组的创建和遍历,是PHP开发里最基础也最常用的操作。简单来说,创建数组可以通过多种灵活的方式实现,比如直接用

array()
登录后复制
登录后复制

构造函数、现代的方括号

[]
登录后复制
登录后复制

语法,甚至隐式赋值。而遍历数组,最核心且推荐的方式是

foreach
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

循环,它能优雅地处理各种类型的数组,当然,

for
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

循环也常用于索引数组。理解数组的结构是选择合适创建和遍历方式的关键。

解决方案

创建PHP数组其实挺随性的,不像有些语言那么死板。

创建数组:

  1. 使用

    array()
    登录后复制
    登录后复制

    构造函数 (传统方式):
    这是PHP早期就有的方式,至今仍然完全可用。

    // 索引数组
    $fruits = array("apple", "banana", "orange");
    echo $fruits[0]; // 输出: apple
    
    // 关联数组
    $person = array(
        "name" => "Alice",
        "age" => 30,
        "city" => "New York"
    );
    echo $person["name"]; // 输出: Alice
    登录后复制
  2. 使用方括号

    []
    登录后复制
    登录后复制

    语法 (PHP 5.4+ 推荐):
    这种方式更简洁,也更符合现代编程语言的习惯,个人觉得可读性也更好。

    // 索引数组
    $colors = ["red", "green", "blue"];
    echo $colors[1]; // 输出: green
    
    // 关联数组
    $product = [
        "id" => 101,
        "name" => "Laptop",
        "price" => 1200.00
    ];
    echo $product["name"]; // 输出: Laptop
    登录后复制
  3. 隐式创建或赋值:
    当你给一个变量的数组下标赋值时,如果这个变量还不是数组,PHP会自动把它变成一个数组。

    $data = []; // 先初始化为空数组是个好习惯
    $data[] = "first item"; // 索引0
    $data[] = "second item"; // 索引1
    $data["key"] = "value"; // 关联键
    
    echo $data[0]; // 输出: first item
    echo $data["key"]; // 输出: value
    登录后复制

    这里有个小细节,如果直接

    $data[] = "item";
    登录后复制

    而不先声明

    $data = [];
    登录后复制

    ,PHP也能处理,但显式声明能让代码更清晰。

    立即学习PHP免费学习笔记(深入)”;

遍历数组:

遍历数组就是把数组里的每个元素都走一遍,取到它的值,有时也需要它的键。

  1. foreach
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制

    循环 (最常用,推荐):

    foreach
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制

    是PHP遍历数组的瑞士军刀,它能处理索引数组和关联数组,代码也最简洁。

    $fruits = ["apple", "banana", "orange"];
    foreach ($fruits as $fruit) {
        echo $fruit . "/n";
    }
    // 输出:
    // apple
    // banana
    // orange
    
    $person = [
        "name" => "Bob",
        "age" => 25,
        "occupation" => "Engineer"
    ];
    foreach ($person as $key => $value) {
        echo $key . ": " . $value . "/n";
    }
    // 输出:
    // name: Bob
    // age: 25
    // occupation: Engineer
    登录后复制

    个人觉得,除非有非常特殊的性能或索引需求,

    foreach
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制

    几乎是所有遍历场景的首选。它把键值对的获取封装得很好,你不用担心索引越界或者键不存在的问题。

  2. for
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制

    循环 (适用于索引数组):

    for
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制

    循环主要用于那些键是连续数字(0, 1, 2…)的索引数组。你需要手动管理循环变量和数组长度。

    $colors = ["red", "green", "blue", "yellow"];
    for ($i = 0; $i < count($colors); $i++) {
        echo $colors[$i] . "/n";
    }
    // 输出:
    // red
    // green
    // blue
    // yellow
    登录后复制

    for
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制

    循环时,记得

    count($colors)
    登录后复制

    最好在循环前计算一次,避免每次迭代都重新计算数组长度,这算是一个小小的优化点。

  3. while
    登录后复制

    循环结合

    list()
    登录后复制

    each()
    登录后复制
    登录后复制
    登录后复制
    登录后复制

    (不推荐,

    each()
    登录后复制
    登录后复制
    登录后复制
    登录后复制

    已弃用):

    each()
    登录后复制
    登录后复制
    登录后复制
    登录后复制

    函数在 PHP 7.2 中已弃用,在 PHP 8.0 中被移除。所以,这种方式现在基本不会用了,但作为历史知识,提一下也无妨。它过去常用来在循环中同时获取键和值,并且内部维护一个数组指针。

    // $data = ["a" => 1, "b" => 2];
    // while (list($key, $value) = each($data)) {
    //     echo "$key: $value/n";
    // }
    登录后复制

    现在如果你需要类似

    each()
    登录后复制
    登录后复制
    登录后复制
    登录后复制

    的功能,可以考虑使用

    reset()
    登录后复制

    next()
    登录后复制

    配合

    key()
    登录后复制

    current()
    登录后复制

    手动管理数组指针,但这通常比

    foreach
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制

    复杂得多。

PHP中索引数组和关联数组有什么区别?如何选择?

PHP数组的强大之处在于它的混合性,但理解索引数组和关联数组是基础。它们的核心区别在于键(key)的类型

索引数组 (Indexed Arrays):

  • 键是整数,通常从0开始,自动递增。
  • 当你创建一个数组而不指定键时,PHP默认会创建一个索引数组。
  • 示例:

    $numbers = [10, 20, 30]; // 键分别是 0, 1, 2
    echo $numbers[0]; // 输出 10
    登录后复制
  • 适用场景: 当数据集合的顺序很重要,或者你只关心值的列表时。例如,一个用户列表、一个商品ID列表。访问速度快,因为是基于数字索引。

关联数组 (Associative Arrays):

  • 键是字符串。你可以用有意义的字符串作为键来标识每个值。
  • 这使得数组更像是一个键值对的映射(map)或字典(dictionary)。
  • 示例:

    $userProfile = [
        "username" => "john_doe",
        "email" => "john@example.com",
        "age" => 28
    ];
    echo $userProfile["email"]; // 输出 john@example.com
    登录后复制
  • 适用场景: 当你需要通过一个描述性的名称来访问数据时。例如,用户配置、HTTP请求参数、数据库查询结果的单行数据。它提供了更好的可读性和自我解释性。

如何选择?
这真的取决于你的数据模型和需求。

  • 如果你的数据是一个有序列表,且访问时通常通过位置(第一个、第二个),那就用索引数组。比如一个文件的行集合。
  • 如果你的数据有明确的属性名称,需要通过这些名称来获取对应的值,那就用关联数组。比如一个用户对象,它的姓名、年龄、邮箱等属性。

PHP的灵活性在于你可以混合使用这两种类型,比如一个数组的某些元素是索引的,另一些是关联的。但这通常不推荐,因为它会降低代码的可读性和维护性。保持数组类型的一致性是个好习惯。

遍历PHP数组时,如何获取键和值?有哪些高级用法?

在遍历PHP数组时,获取键和值是核心操作,而

foreach
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

循环提供了最直接和优雅的方式。

获取键和值:

  1. foreach ($array as $key => $value)
    登录后复制

    :
    这是最推荐的方式,它在每次迭代时,将当前元素的键赋值给

    $key
    登录后复制
    登录后复制

    变量,将值赋值给

    $value
    登录后复制
    登录后复制

    变量。

    $settings = [
        "theme" => "dark",
        "language" => "en",
        "notifications" => true
    ];
    
    foreach ($settings as $settingKey => $settingValue) {
        echo "Setting: " . $settingKey . " = " . (is_bool($settingValue) ? ($settingValue ? "true" : "false") : $settingValue) . "/n";
    }
    // 输出:
    // Setting: theme = dark
    // Setting: language = en
    // Setting: notifications = true
    登录后复制

    这里我用了一个三元运算符来处理布尔值的输出,让结果更直观。

    Magick

    Magick

    无代码AI工具,可以构建世界级的AI应用程序。

    Magick99


    查看详情
    Magick

  2. foreach ($array as $value)
    登录后复制

    (只获取值):
    如果你只关心数组中的值,可以省略

    $key
    登录后复制
    登录后复制

    部分。PHP会将当前元素的值直接赋给

    $value
    登录后复制
    登录后复制

    $tasks = ["Write code", "Review PR", "Deploy"];
    foreach ($tasks as $task) {
        echo "Task: " . $task . "/n";
    }
    // 输出:
    // Task: Write code
    // Task: Review PR
    // Task: Deploy
    登录后复制
  3. for
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制

    循环获取键和值 (仅限索引数组):
    对于索引数组,循环变量

    $i
    登录后复制

    就是键。

    $items = ["itemA", "itemB", "itemC"];
    for ($i = 0; $i < count($items); $i++) {
        echo "Key: " . $i . ", Value: " . $items[$i] . "/n";
    }
    登录后复制

高级用法和函数:

除了基本的循环,PHP还提供了一些内置函数,可以实现更高级的数组遍历和操作:

  1. array_map()
    登录后复制
    登录后复制

    :
    对数组中的每个元素应用回调函数,并返回一个新的数组。这很适合批量转换数据。

    $numbers = [1, 2, 3, 4];
    $squaredNumbers = array_map(function($n) {
        return $n * $n;
    }, $numbers);
    print_r($squaredNumbers);
    // 输出: Array ( [0] => 1 [1] => 4 [2] => 9 [3] => 16 )
    登录后复制
    array_map
    登录后复制
    登录后复制
    登录后复制

    也可以处理多个数组作为输入,回调函数接收多个参数。

  2. array_filter()
    登录后复制
    登录后复制

    :
    用回调函数过滤数组中的元素,只保留那些回调函数返回

    true
    登录后复制

    的元素,并返回一个新的数组。

    $scores = [85, 92, 78, 65, 95];
    $passingScores = array_filter($scores, function($score) {
        return $score >= 80;
    });
    print_r($passingScores);
    // 输出: Array ( [0] => 85 [1] => 92 [4] => 95 )
    // 注意:键保持不变
    登录后复制

    如果你想重置键,可以再用

    array_values()
    登录后复制

  3. array_walk()
    登录后复制

    :
    对数组中的每个元素应用用户自定义函数。与

    array_map
    登录后复制
    登录后复制
    登录后复制

    不同的是,

    array_walk
    登录后复制
    登录后复制
    登录后复制

    不返回新数组,它是在原数组上操作(如果回调函数通过引用修改了值)。

    $names = ["alice", "bob", "charlie"];
    array_walk($names, function(&$name, $key) { // 注意这里的 & 符号
        $name = ucfirst($name); // 将首字母大写
    });
    print_r($names);
    // 输出: Array ( [0] => Alice [1] => Bob [2] => Charlie )
    登录后复制
    array_walk
    登录后复制
    登录后复制
    登录后复制

    的回调函数可以接收值、键和可选的用户数据。

  4. array_reduce()
    登录后复制
    登录后复制

    :
    将数组归约为单一的值。它通过迭代地将回调函数应用于累加器和数组的每个值来实现。

    $numbers = [1, 2, 3, 4, 5];
    $sum = array_reduce($numbers, function($carry, $item) {
        return $carry + $item;
    }, 0); // 0 是初始值
    echo "Sum: " . $sum; // 输出: Sum: 15
    登录后复制
    array_reduce
    登录后复制

    在计算总和、连接字符串、构建复杂数据结构时非常有用。

这些高级函数提供了一种更“函数式编程”的风格来处理数组,代码通常更简洁,意图也更明确,尤其是在处理大型数据集时,可以避免手动循环带来的冗余代码。

PHP数组遍历中常见的性能陷阱和优化建议有哪些?

在PHP中处理数组,尤其是在大型应用或处理大数据量时,性能优化是个绕不开的话题。一些看似不起眼的小习惯,可能成为性能瓶颈。

常见的性能陷阱:

  1. for
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制

    循环条件中重复计算

    count()
    登录后复制
    登录后复制
    登录后复制

    :
    这是最经典的陷阱之一。

    $largeArray = range(0, 100000); // 假设一个大数组
    for ($i = 0; $i < count($largeArray); $i++) { // 每次迭代都调用 count()
        // ... do something
    }
    登录后复制
    count()
    登录后复制
    登录后复制
    登录后复制

    函数虽然很快,但在一个百万次循环中被调用百万次,累积起来的开销就不容忽视了。PHP解释器每次都要计算数组长度。

  2. 不必要的数组复制:
    PHP在某些操作中会创建数组的副本,尤其是当数组作为函数参数传递时,如果函数内部修改了数组,且没有通过引用传递,就会发生复制。大数组的复制会消耗大量内存和CPU时间。

    function processArray($arr) { // $arr 是副本
        $arr[] = "new_item"; // 修改的是副本
        return $arr;
    }
    $myArray = range(0, 100000);
    $newArray = processArray($myArray); // 这里发生了复制
    登录后复制
  3. 在循环内部执行数据库查询或文件I/O:
    这不完全是数组遍历本身的陷阱,但经常在遍历数组时发生。

    $userIds = [1, 2, 3, ...];
    foreach ($userIds as $userId) {
        // 每次循环都执行一个数据库查询
        $user = DB::query("SELECT * FROM users WHERE id = ?", [$userId]);
        // ...
    }
    登录后复制

    这种“N+1查询”问题是性能杀手。

  4. 使用

    array_merge()
    登录后复制

    array_unique()
    登录后复制

    等函数在循环内部处理大数组:
    这些函数在处理大数组时本身就有一定开销,如果在循环中频繁调用,性能会急剧下降。它们通常会创建新的数组。

优化建议:

  1. 预先缓存

    count()
    登录后复制
    登录后复制
    登录后复制

    值 (针对

    for
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制

    循环):

    $largeArray = range(0, 100000);
    $count = count($largeArray); // 提前计算一次
    for ($i = 0; $i < $count; $i++) {
        // ... do something
    }
    登录后复制

    这个改动虽小,但对

    for
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制

    循环的性能提升是显著的。

  2. 优先使用

    foreach
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制

    循环:
    在大多数情况下,

    foreach
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制

    for
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制

    更高效,因为它不需要你手动管理索引,内部实现更优化,并且在遍历关联数组时是唯一的合理选择。对于索引数组,现代PHP版本中

    foreach
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制

    的性能通常也与优化过的

    for
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制

    循环不相上下,甚至更好。

  3. 通过引用传递大数组给函数:
    如果函数需要修改数组,并且你不希望创建副本,可以通过引用传递。

    function processArrayByRef(&$arr) { // 注意 & 符号
        $arr[] = "new_item"; // 修改的是原数组
    }
    $myArray = range(0, 100000);
    processArrayByRef($myArray); // 没有发生复制
    登录后复制

    但使用引用要小心,它可能导致意外的副作用,降低代码的可预测性。

  4. 批量处理数据库查询和文件I/O:
    对于N+1查询问题,通常可以通过一次性获取所有需要的数据来解决。

    $userIds = [1, 2, 3, ...];
    // 使用 IN 子句一次性查询所有用户
    $users = DB::query("SELECT * FROM users WHERE id IN (?)", [implode(',', $userIds)]);
    // 然后在内存中处理 $users 数组
    foreach ($userIds as $userId) {
        // ... 从 $users 数组中查找对应用户,而不是再次查询数据库
    }
    登录后复制

    类似地,文件操作也应考虑批量读写。

  5. 合理使用

    array_map()
    登录后复制
    登录后复制

    ,

    array_filter()
    登录后复制
    登录后复制

    ,

    array_reduce()
    登录后复制
    登录后复制

    等函数:
    这些函数在内部通常是高度优化的C代码,比手写PHP循环可能更快。它们也让代码更简洁、意图更明确。但要权衡它们的开销,例如

    array_map
    登录后复制
    登录后复制
    登录后复制

    会创建新数组,如果原数组很大且不需要新数组,可能就不如

    array_walk
    登录后复制
    登录后复制
    登录后复制

  6. 避免在循环中创建大量临时对象或变量:
    每次循环都

    new
    登录后复制

    一个对象或创建大量不必要的临时变量,会增加内存开销和垃圾回收的压力。

  7. 理解 PHP 数组的底层实现:
    PHP 数组是哈希表,这意味着无论是索引数组还是关联数组,其查找、插入、删除操作的平均时间复杂度都是 O(1)。但在极端情况下(例如哈希冲突严重),性能可能会下降。通常情况下,你不需要过度担心底层实现,但知道这一点有助于理解其灵活性和性能特征。

总之,优化数组遍历并非一概而论,需要根据具体的应用场景和数组大小来选择最合适的方法。大部分时候,

foreach
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

配合合理的数据结构和批量操作,就能满足性能需求。

以上就是php数组如何创建和遍历_php创建数组与循环遍历教程的详细内容,更多请关注php中文网其它相关文章!

https://www.php.cn/faq/1523091.html

发表回复

Your email address will not be published. Required fields are marked *