Hướng dẫn php reference counting - đếm tham chiếu php

Chào các bạn, chắc hẳn ai trong chúng ta đã biết về biến và tham chiếu khi học các môn cơ sở lập trình khi mới vào nghề. Thế nhưng khi làm việc với PHP một vài người tưởng như đã quên là nó có tồn tại, hoặc một vài người thì biết nó có nhưng lại không biết xài nó như nào; thậm chí một vài trong chúng ta đã từng xài nhưng lại phát sinh một số lỗi không ngờ tới.

Nội dung chính

  • Biến tham chiếu (reference variables)
  • Tham chiếu trong object và array
  • Tham chiếu trong function
  • Một số vấn đề khi dùng reference variable
  • Reference object
  • Reference array
  • Kết luận
  • Nguồn tham khảo

Nội dung chính

  • Biến tham chiếu (reference variables)
  • Tham chiếu trong object và array
  • Tham chiếu trong function
  • Một số vấn đề khi dùng reference variable
  • Reference object
  • Reference array
  • Kết luận
  • Nguồn tham khảo

Nội dung chính

  • Biến tham chiếu (reference variables)
  • Tham chiếu trong object và array
  • Tham chiếu trong function
  • Một số vấn đề khi dùng reference variable
  • Reference object
  • Reference array
  • Kết luận
  • Nguồn tham khảo

Để giúp các bạn hiểu rõ hơn về biến và tham chiếu trong PHP, đồng thời cũng giúp mình có cơ hội được tìm hiểu kỹ hơn về tính năng, đặc điểm này, hôm nay mình sẽ viết về vấn đề tham chiếu với biến trong PHP.

Để đảm bảo sự chính xác nguyên vẹn của thuật ngữ cũng như các định nghĩa, trong bài viết này mình xin phép dùng một số từ nguyên mẫu so với định nghĩa của nó:

  • $a;
    $b = &$a;
    
    3: Lớp
  • $a;
    $b = &$a;
    
    4 ,
    $a;
    $b = &$a;
    
    5: Các thuộc tính trong class
  • $a;
    $b = &$a;
    
    6: kiểu dữ liệu là các đối tượng (có thể là object hoặc class)
  • $a;
    $b = &$a;
    
    7: kiểu dữ liệu là mảng
  • $a;
    $b = &$a;
    
    8: tham chiếu

Trong bài này, mình định nghĩa hai functions giúp mình in ra giá trị dễ nhìn hơn:

// Dùng để log trên màn hình console
function beatifyLog(...$arr)
{
    foreach ($arr as $item) {
        print_r($item);
    }
}
// Dùng để log trên giao diện html
function beatifyHtml(...$arr)
{
    echo '
';
    foreach ($arr as $item) {
        print_r($item);
    }
    echo '
'; }

Biến tham chiếu (reference variables)

Biến

$a;
$b = &$a;
9 lúc này được gọi là biến tham chiếu của
$arr = [
    'key'       => 'value',
    'other_key' => 'other_value',
];
$obj = (object) $arr;

$arr2 = $arr;
$obj2 = $obj;

$arr['key'] = 'another_value';
$obj2->key  = 'another_value';

beatifyLog('arr: ', $arr, 'arr2: ', $arr2);
echo "=====\n";
beatifyLog('obj: ', $obj, 'obj2: ', $obj2);
0, còn gọi là (alias), khi
$a;
$b = &$a;
9 và
$arr = [
    'key'       => 'value',
    'other_key' => 'other_value',
];
$obj = (object) $arr;

$arr2 = $arr;
$obj2 = $obj;

$arr['key'] = 'another_value';
$obj2->key  = 'another_value';

beatifyLog('arr: ', $arr, 'arr2: ', $arr2);
echo "=====\n";
beatifyLog('obj: ', $obj, 'obj2: ', $obj2);
0 trỏ về cùng một địa chỉ bộ nhớ trên máy. Lúc này,
$arr = [
    'key'       => 'value',
    'other_key' => 'other_value',
];
$obj = (object) $arr;

$arr2 = $arr;
$obj2 = $obj;

$arr['key'] = 'another_value';
$obj2->key  = 'another_value';

beatifyLog('arr: ', $arr, 'arr2: ', $arr2);
echo "=====\n";
beatifyLog('obj: ', $obj, 'obj2: ', $obj2);
0 hoặc
$a;
$b = &$a;
9 thay đổi giá trị thì biến còn lại cũng sẽ thay đổi theo.

$a;
$b = &$a;

Ví dụ:

Hướng dẫn php reference counting - đếm tham chiếu php

Tham chiếu trong object và array

Trong PHP, các biến object là tham chiếu, trong khi mảng thì không. Ví dụ:

$arr = [
    'key'       => 'value',
    'other_key' => 'other_value',
];
$obj = (object) $arr;

$arr2 = $arr;
$obj2 = $obj;

$arr['key'] = 'another_value';
$obj2->key  = 'another_value';

beatifyLog('arr: ', $arr, 'arr2: ', $arr2);
echo "=====\n";
beatifyLog('obj: ', $obj, 'obj2: ', $obj2);

Kết quả là:

Như vậy muốn array tham chiếu được thì như thế nào? Minh xin chia sẻ một cách dùng trong foreach hữu ích giúp chúng ta có được điều đó:

$arr = [1, 2, 3, 4,];
beatifyLog('Initial Value: ', $arr);
echo "=====\n";
foreach ($arr as $item) {
    $item++;
}
beatifyLog('Foreach without reference: ', $arr);
echo "=====\n";
foreach ($arr as &$item) {
    $item++;
}
beatifyLog('Foreach with reference: ', $arr);

Và đây là kết quả sau khi chạy các dòng lệnh trên:

Tham chiếu trong function

PHP có hỗ trợ biến tham chiếu khi đưa vào function, cú pháp:

function fnName(&$a, $b)
{}

Ở đây

$arr = [
    'key'       => 'value',
    'other_key' => 'other_value',
];
$obj = (object) $arr;

$arr2 = $arr;
$obj2 = $obj;

$arr['key'] = 'another_value';
$obj2->key  = 'another_value';

beatifyLog('arr: ', $arr, 'arr2: ', $arr2);
echo "=====\n";
beatifyLog('obj: ', $obj, 'obj2: ', $obj2);
0 là biến tham chiếu, còn
$a;
$b = &$a;
9 là biến bình thường. Xét ví dụ cụ thể sau:

function test(&$a, $b)
{
    $a++;
    $b++;
}
$a = 3;
$b = 4;
beatifyLog('Before: ', 'a=', $a, '; b=', $b);
echo "\n";
test($a, $b);
beatifyLog('After:  ', 'a=', $a, '; b=', $b);

Kết quả:

Một số vấn đề khi dùng reference variable

Reference object

Reference object

Reference array

  • Kết luận

    Nguồn tham khảo
  • Để giúp các bạn hiểu rõ hơn về biến và tham chiếu trong PHP, đồng thời cũng giúp mình có cơ hội được tìm hiểu kỹ hơn về tính năng, đặc điểm này, hôm nay mình sẽ viết về vấn đề tham chiếu với biến trong PHP.

    $db = [
        '2021-01-02',
        '2020-01-02',
        '2021-01-01',
        '2020-01-05',
        '2019-01-05'
    ];
    
  • Để đảm bảo sự chính xác nguyên vẹn của thuật ngữ cũng như các định nghĩa, trong bài viết này mình xin phép dùng một số từ nguyên mẫu so với định nghĩa của nó:

    $a;
    $b = &$a;
    
    3: Lớp

$a;
$b = &$a;
4 ,
$a;
$b = &$a;
5: Các thuộc tính trong class

// Should be 2021-01-01
$curYear  = new Date(2021, 1, 1);

// Should be 2020-01-01
$prevYear = $curYear;
$prevYear->addYears(-1);

// Should return 2020-01-02, 2021-01-01 and 2020-01-05
beatifyLog('Result:', array_filter($db, function ($a) use ($curYear, $prevYear) {
    return $a >= $prevYear->toString() && $a <= $curYear->toString();
}));

$a;
$b = &$a;
6: kiểu dữ liệu là các đối tượng (có thể là object hoặc class)

$a;
$b = &$a;
7: kiểu dữ liệu là mảng

Kết quả:

Đây là phần mình mong chờ nhất trong bài viết này. Dưới đây mình xin chia sẻ các lỗi mình đã gặp và cách xử lí khi làm việc với reference variable. Dĩ nhiên sẽ còn thiếu rất nhiều trường hợp, mong các bạn có thể chia sẻ thêm để giúp ích hơn cho bài viết của mình cũng như các bạn khác được hiểu rõ hơn.

Để nói về vấn đề này, mình xin đưa ra một bài toán nho nhỏ để minh hoạ nhé.

$a;
$b = &$a;
0

Cho class

$arr = [
    'key'       => 'value',
    'other_key' => 'other_value',
];
$obj = (object) $arr;

$arr2 = $arr;
$obj2 = $obj;

$arr['key'] = 'another_value';
$obj2->key  = 'another_value';

beatifyLog('arr: ', $arr, 'arr2: ', $arr2);
echo "=====\n";
beatifyLog('obj: ', $obj, 'obj2: ', $obj2);
7 cùng các method như bên dưới

class Date
{
    private $d = 0;
    private $m = 0;
    private $Y = 0;

    public function __construct(int $year, int $month, int $day)
    {
        $this->Y = $year;
        $this->m = $month;
        $this->d = $day;
    }

    private function addSubZero(int $i): string
    {
        return $i > 9 ? $i : "0$i";
    }

    public function toString(): string
    {
        $Y = $this->Y;
        $m = $this->addSubZero($this->m);
        $d = $this->addSubZero($this->d);

        return "$Y-$m-$d";
    }

    public function addYears(int $num): Date
    {
        $this->Y += $num;

        return $this;
    }
}

Reference array

Kết luận

$a;
$b = &$a;
1

Nguồn tham khảo

Để giúp các bạn hiểu rõ hơn về biến và tham chiếu trong PHP, đồng thời cũng giúp mình có cơ hội được tìm hiểu kỹ hơn về tính năng, đặc điểm này, hôm nay mình sẽ viết về vấn đề tham chiếu với biến trong PHP.

$a;
$b = &$a;
2

Để đảm bảo sự chính xác nguyên vẹn của thuật ngữ cũng như các định nghĩa, trong bài viết này mình xin phép dùng một số từ nguyên mẫu so với định nghĩa của nó:

Kết luận

Nguồn tham khảo

Nguồn tham khảo

Để giúp các bạn hiểu rõ hơn về biến và tham chiếu trong PHP, đồng thời cũng giúp mình có cơ hội được tìm hiểu kỹ hơn về tính năng, đặc điểm này, hôm nay mình sẽ viết về vấn đề tham chiếu với biến trong PHP.

  • https://www.php.net/manual/en/language.oop5.references.php
  • https://www.php.net/manual/en/language.oop5.cloning.php