最近遇到的幾個PHP小知識點

原文連接:何曉東 博客php

好的框架能提高語言生態,也有時候能把讓PHP程序員成爲框架程序員,而不是更好的後端程序員,例如我這樣的。

測試環境爲 PHP7.4 Windows 10系統laravel

str_replace 函數

一個小需求是相似單詞填空題,從單詞中替換到幾個字母,變成 _,而後給出一些選項,例如 ax n, au h, ab y這樣的,將選項一一對應的替換 _,和原單詞比較,若是一致就是正確選項,本覺得事情很簡單,str_replace 函數支持兩個數組之間的替換,例如程序員

$str = 'ab';
str_replace(['a', 'b'], ['c', 'd'], $str);

# output: cd

同位置交換,因此我寫了這個segmentfault

<?php
# 原單詞是 laugh

$str = 'l__g_';
$replace = 'au h';
$needle = array_fill(0, substr_count($str, '_') - 1, '_');
$replaceArray = array_filter(str_split($replace));

echo str_replace($needle, $replaceArray, $str);

# output: laaga

本覺得很簡單就能夠輸出 laugh,沒有多想,實際上會在第一次 替換 a 的狀況下,直接將全部的 替換爲了 a, 再一次掃描替換已經沒有 _ 了,執行完畢,因此最終結果毫無問題,是我想的簡單了,換個思路只能一個個替換。後端

<?php
# 原單詞是 laugh

$str = 'l__g_';
$replace = 'au h';

$replaceArray = array_filter(str_split($replace));
for ($i = 0; $i < count($replaceArray); $i++) {
    $position = strpos($str, '_');
    $str = substr_replace($str, $replaceArray[$i], $position, 1);
}

echo $str;
對象與數組的拷貝差別

原想的操做是根據最初的對象數值,例若有 10 個子屬性,而後給 10 個屬性附上一個新鍵值,最後獲得的並非想要的,一個 demo 代碼 此問題常見於 laravel 框架數組

<?php
$object = (object)[
        (object)[
            'a' => 1,
            'b' => 2,
        ],
        (object)[
            'a' => 3,
            'b' => 4,
        ]
    ];

    $result = [];
    for ($i = 0 ; $i < 2; $i++) {
        foreach ($object as $key => $value) {
            $value->type = $i;
            $result[] = $value;
        }
    }

    return $result;

// output: [{"a":1,"b":2,"type":1},{"a":3,"b":4,"type":1},{"a":1,"b":2,"type":1},{"a":3,"b":4,"type":1}]

指望輸出的前兩個的 type 應該是 0,後兩個是 1,然而結果全是 1,致使的緣由是對象的複製是淺複製,他們實際指向的是統一內存地址,循環的最後把值改爲 1 了,因此全都是 type : 1
參考 對象複製文檔框架

測試代碼:函數

<?php
$object = (object)[
        'a' => 1,
        'b' => 2,
    ];

    $a = $object;
    $object->a = 'a';
    echo $object->a . PHP_EOL;
    echo $a->a;

# output: a a

與之相反的數組的複製,數組的拷貝是值傳遞。PHP 在管理內存方面有一個機制叫寫時複製(COW,Copy On Write),保證了變量間複製值不浪費內存:當一個變量的值複製到另外一個變量時,PHP 沒有爲複製值使用更多的內存,相反,它會更新符號表來講明兩個變量擁有相同的內存塊,因此當執行下面的代碼時並無建立一個新的數組,在修改其中的一個值時,PHP纔會將分配所需的內存來複制。oop

測試代碼:測試

<?php
$array = [
        'a' => 1,
        'b' => 2,
    ];

    $a = $array;
    $array['a'] = 'a';
    echo $array['a'] . PHP_EOL;
    echo $a['a'];

# output: a 1

主要是基礎知識不夠好,才踩坑,避免下次再犯錯。

來一塊兒提高 --> 基礎知識

相關文章
相關標籤/搜索