Rumah pembangunan bahagian belakang tutorial php 被忽略的魔法——php引用之推迟赋值(后期数据延迟绑定)

被忽略的魔法——php引用之推迟赋值(后期数据延迟绑定)

Jun 13, 2016 pm 12:20 PM
nbsp uid

被忽略的魔法——php引用之延迟赋值(后期数据延迟绑定)

       看到这个主题大家知道我今天要说的是php的变量引用特性,但是延迟赋值又是怎么回事呢?这个主要是我近期优化一些功能时的一个想法,我觉得还算不错,就打算记录下来。看一下下面的伪代码:

// 这段代码有人会说为啥不用联表,因为有些业务需求不用联表的效率是联表的3到20倍// 我的项目里基本都是此类写法,比之前联表效率提升很多$a = DB::query("select id from a");$aid = "";foreach($a as $v){	$aid .= $v['id'].','; }$aid = substr($aid, 0 , -1);if($aid){	$b = DB::query("select * from b where aid in ({$aid})");		// 此处省略}
Salin selepas log masuk

         之所以用这段代码举例,因为类似这样的代码很多,大家比较容易理解,但不一定适合用后期延迟赋值,因为这样更容理解,且效率差不多,不过可以和后期延迟赋值形成鲜明对比,让大家更容理解下面的实现的方式。

       看完上面的例子我们再看一个复杂的需求,要求数据是获取一人的最近10篇文章列表,且读取每篇文章5条评论,并包含文章发起者和评论人的id,姓名,把是数据打包成指定格式的json返回给客户端,看下面的代码:

 

// 这种需求用联表获取用户信息远没有搜集用户id做in查询效率高$data = array();$article = DB::query("select id,uid,title,content from article where uid={$_GET['uid']} order by id desc limit 10");foreach($article as $v){	$uid = $v['uid'];	$comment = DB::query("select id,uid,content from comment where aid={$v['id']} order by id asc limit 5");		foreach($comment as $value){		$uid .= ','.$value['uid'];	}	// 这里第二个参数我们要求DB类返回的数组以uid为索引	$member = DB::query("select uid,username from user where uid in({$uid})", 'uid');	$commentList = array();	$data[] = array(		'id' => $v['id'],		'title' => $v['title'],		'content' => $v['content'],		'uid' => $v['uid'],		'username' => $member[$v['uid']]['username'],		'comment' => &$commentList	);	foreach($comment as $value){		$commentList[] = array(			'id' => $value['id'],			'content' => $value['content'],			'uid' => $value['uid'],			'username' => $member[$value['uid']]['username']		)	}}	echo json_encode($data);exit;
Salin selepas log masuk

       细心看这段代码就会发现其中$data[]['comment']的值最开始就引用了变量$commentList,之后在后面更改了$commentList的值,同时导致$data[]['comment']值跟着一起发生了改变,这里也是后期延迟赋值,但是比较简单,可以据此了解一下这个实现原理。

       我相信大多数人都写过类似的代码,也很少有人觉得这段代码会有问题。我来分析一下这块的逻辑,评论信息因为要每篇文章获取5条,这个没法用简单的sql合并成一条,由于需求只是获取10篇文章,写复杂的sql处理反而不如循环查询的效率(如果你内网延迟较低的情况下),为啥说复杂sql的处理效率慢,如果你考虑的是几千条数据都一样没啥需要注意,但是如果处理的是千万级别的数据量,复杂sql很多情况下不如简单的sql效率高,那么这里就采用循环查询没法继续优化。但是我们看用户信息也在循环里进行查询,这个很不好了,我的项目组里很不希望见到这样的代码的,10篇帖子都是一个人发起的,近50条评论会有很多活跃用户的数据,这样每次循环查询其实查询到重复用户信息的概率非常高,在一个业务逻辑里最好不要从数据库获取重复信息而是复用。如何能让让用户信息达到复用呢?可以在组装最终数据前循环获取文章的评论信息,之后收集用户id,然后再获取用户信息,之后组装最终的数据。这是一种比较简单的解决方案,不是我们今天的重点,下面看一种优雅的处理方式——延迟赋值。

// 这种需求用联表获取用户信息远没有搜集用户id做in查询效率高$data = array();$article = DB::query("select id,uid,title,content from article where uid={$_GET['uid']} order by id desc limit 10");$member = array();foreach($article as $v){	$comment = DB::query("select id,uid,content from comment where aid={$v['id']} order by id asc limit 5");	$commentList = array();	$data[] = array(		'id' => $v['id'],		'title' => $v['title'],		'content' => $v['content'],		'uid' => $v['uid'],		'username' => &$member[$v['uid']]['username'],		'comment' => &$commentList	);	foreach($comment as $value){		$commentList[] = array(			'id' => $value['id'],			'content' => $value['content'],			'uid' => $value['uid'],			'username' => &$member[$value['uid']]['username']		)	}}$uid = array_keys($member);if($uid){	$uid = implode(',', $uid);	$user = DB::query("select uid,username from user where uid in({$uid})", 'uid');	foreach($member as $uid => $value){		$member[$uid]['username'] = $user[$uid]['username'];	}	unset($member,$user);}echo json_encode($data);exit;
Salin selepas log masuk

        这段代码和之前不太一样了,最明显的就是最下面多了一段代码,而且暂时还不知道究竟是干嘛,好像没啥用,我们一步步的看看,首先在循环文章数据前初始化了一个变量$member = array();之后在循环里少了$uid的赋值,以及循环收集评论人的id,并且查询用户数据的sql也不见了,好像到了最下面那段看不懂的代码地方。仔细找了找还发现&$member[$v['uid']]['username']和&$member[$value['uid']]['username']地方多了&引用符号,这就是为啥循环里少了写代码的奥秘。回想一下之前发现$commentList被引用之后在后面进行赋值的,并且改变了$data[]['comment']。这的道理是一样的,先不查询用户信息,只进行一个空的引用,在引用一个不存在的变量时php会先创建这个变量,例如&$member[$v['uid']]['username'],php检测$member是一个数组已经声明,但是$member[$v['uid']]['username']不存在就在内存创建并且值为null。

       当循环完文章数据后打印会发现username的信息都是null,当然之前并没用用户信息,php在引用赋值的时候帮我们给了一个null值。之后通过$uid = array_keys($member);获取所有用户的id信息,

为什么array_keys能获取用户id,因为php在引用的时候帮我们创建了$member数组呀,注意一下这里的uid是不重复的哟,之后我们去user表用in检索用户信息,一定注意这里不能把返回的数据赋值给$member因为之前的数据都是引用$member里的数据,如果这里覆盖了$member,内存里两个变量的地址就不一样了,相当于重新创建了一个数组,我们这里赋值给$user,下面的循环是干什么的,当然是修改之前被引用数据的赋值了,我们循环$member变量把$user[$uid]['username']赋值给$member[$uid]['username'],从而改变引用变量的值。在我们把数据绑定到引用变量后千万不要忽略用uset把$member删除了,主要是防止之后的代码里出现操作$member变量的代码,不小心就会把之前绑定好的数据覆盖掉。为啥删除$member之后绑定的数据没有丢失,主要是引用的特性,当多个变量引用一个内存地址时,删除其中一个变量不影响其它变量,除非把所有变量都删除,才会真的删除内存里的数据。php手册是这么解释的 unset 一个引用,只是断开了变量名和变量内容之间的绑定。这并不意味着变量内容被销毁了”。unset($user);只是因为$user是一个临时变量,使用完可以直接从内存释放了。

 

       关于这种编程方式我命名为后期数据延迟绑定,之所以标题是延迟变量赋值主要是让大家便于理解。Php中引用的作用非常广泛,本文所举的例子也只局部的一种使用方法,用来解决编程中遇到类似业务需求的一种处理方式,当然后期数据延迟绑定的编程方法也有很广的使用,希望大家不要局限在本文例子的场景上。针对本文例子是我们编程中最常用的一种问题,我编写了一个函数用来处理数据延迟绑定,减少每个地方都要编写数据绑定的逻辑。

/** * 数据延迟绑定通用方法 *  * @access public * @param array $bindingVar		待绑定的变量 * @param array	$data		待绑定的数据 * @param mixed	$default	默认值 * @return void  */function bindingData(&$bindingVar, $data, $default=''){	foreach($bindingVar as $key => $tmp){		foreach($tmp as $k => $v){			$bindingVar[$key][$k] = isset($data[$key][$k]) ? $data[$key][$k] : $default;		}	}		unset($bindingVar);}
Salin selepas log masuk


 

    采用这个函数我们能把之前处理数据绑定的代码部分改成下面这样:

 

$uid = array_keys($member);if($uid){	$user = DB::query("select uid,username from user where uid in({$uid})", 'uid');	bindingData($member, $user);	unset($member,$user);}
Salin selepas log masuk


 

 

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

Video Face Swap

Video Face Swap

Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Penyelesaian: Organisasi anda memerlukan anda menukar PIN anda Penyelesaian: Organisasi anda memerlukan anda menukar PIN anda Oct 04, 2023 pm 05:45 PM

Mesej "Organisasi anda memerlukan anda menukar PIN anda" akan muncul pada skrin log masuk. Ini berlaku apabila had tamat tempoh PIN dicapai pada komputer menggunakan tetapan akaun berasaskan organisasi, di mana mereka mempunyai kawalan ke atas peranti peribadi. Walau bagaimanapun, jika anda menyediakan Windows menggunakan akaun peribadi, sebaiknya mesej ralat tidak akan muncul. Walaupun ini tidak selalu berlaku. Kebanyakan pengguna yang mengalami ralat melaporkan menggunakan akaun peribadi mereka. Mengapa organisasi saya meminta saya menukar PIN saya pada Windows 11? Ada kemungkinan akaun anda dikaitkan dengan organisasi dan pendekatan utama anda adalah untuk mengesahkan perkara ini. Menghubungi pentadbir domain anda boleh membantu! Selain itu, tetapan dasar tempatan yang salah konfigurasi atau kunci pendaftaran yang salah boleh menyebabkan ralat. Sekarang ni

Cara melaraskan tetapan sempadan tetingkap pada Windows 11: Tukar warna dan saiz Cara melaraskan tetapan sempadan tetingkap pada Windows 11: Tukar warna dan saiz Sep 22, 2023 am 11:37 AM

Windows 11 membawa reka bentuk yang segar dan elegan ke hadapan antara muka moden membolehkan anda memperibadikan dan menukar butiran terbaik, seperti sempadan tingkap. Dalam panduan ini, kami akan membincangkan arahan langkah demi langkah untuk membantu anda mencipta persekitaran yang mencerminkan gaya anda dalam sistem pengendalian Windows. Bagaimana untuk menukar tetapan sempadan tetingkap? Tekan + untuk membuka apl Tetapan. WindowsSaya pergi ke Pemperibadian dan klik Tetapan Warna. Perubahan Warna Tetingkap Sempadan Tetapan Tetingkap 11" Lebar="643" Tinggi="500" > Cari pilihan Tunjukkan warna aksen pada bar tajuk dan sempadan tetingkap, dan togol suis di sebelahnya. Untuk memaparkan warna aksen pada menu Mula dan bar tugas Untuk memaparkan warna tema pada menu Mula dan bar tugas, hidupkan Tunjukkan tema pada menu Mula dan bar tugas

Bagaimana untuk menukar warna bar tajuk pada Windows 11? Bagaimana untuk menukar warna bar tajuk pada Windows 11? Sep 14, 2023 pm 03:33 PM

Secara lalai, warna bar tajuk pada Windows 11 bergantung pada tema gelap/terang yang anda pilih. Walau bagaimanapun, anda boleh menukarnya kepada mana-mana warna yang anda mahu. Dalam panduan ini, kami akan membincangkan arahan langkah demi langkah untuk tiga cara mengubahnya dan memperibadikan pengalaman desktop anda untuk menjadikannya menarik secara visual. Adakah mungkin untuk menukar warna bar tajuk tetingkap aktif dan tidak aktif? Ya, anda boleh menukar warna bar tajuk tetingkap aktif menggunakan apl Tetapan, atau anda boleh menukar warna bar tajuk tetingkap tidak aktif menggunakan Registry Editor. Untuk mempelajari langkah-langkah ini, pergi ke bahagian seterusnya. Bagaimana untuk menukar warna bar tajuk dalam Windows 11? 1. Tekan + untuk membuka tetingkap tetapan menggunakan apl Tetapan. WindowsSaya pergi ke "Peribadikan" dan kemudian

Masalah Ralat OOBELANGUAGE dalam Pembaikan Windows 11/10 Masalah Ralat OOBELANGUAGE dalam Pembaikan Windows 11/10 Jul 16, 2023 pm 03:29 PM

Adakah anda melihat "Masalah berlaku" bersama-sama dengan pernyataan "OOBELANGUAGE" pada halaman Pemasang Windows? Pemasangan Windows kadangkala terhenti kerana ralat tersebut. OOBE bermaksud pengalaman di luar kotak. Seperti yang ditunjukkan oleh mesej ralat, ini ialah isu yang berkaitan dengan pemilihan bahasa OOBE. Tiada apa yang perlu dibimbangkan, anda boleh menyelesaikan masalah ini dengan penyuntingan pendaftaran yang bagus dari skrin OOBE itu sendiri. Pembetulan Pantas – 1. Klik butang “Cuba Semula” di bahagian bawah apl OOBE. Ini akan meneruskan proses tanpa gangguan lagi. 2. Gunakan butang kuasa untuk menutup paksa sistem. Selepas sistem dimulakan semula, OOBE harus diteruskan. 3. Putuskan sambungan sistem daripada Internet. Lengkapkan semua aspek OOBE dalam mod luar talian

Bagaimana untuk mendayakan atau melumpuhkan pratonton lakaran kecil bar tugas pada Windows 11 Bagaimana untuk mendayakan atau melumpuhkan pratonton lakaran kecil bar tugas pada Windows 11 Sep 15, 2023 pm 03:57 PM

Lakaran kecil bar tugas boleh menjadi menyeronokkan, tetapi ia juga boleh mengganggu atau menjengkelkan. Memandangkan kekerapan anda menuding di atas kawasan ini, anda mungkin telah menutup tetingkap penting secara tidak sengaja beberapa kali. Kelemahan lain ialah ia menggunakan lebih banyak sumber sistem, jadi jika anda telah mencari cara untuk menjadi lebih cekap sumber, kami akan menunjukkan kepada anda cara untuk melumpuhkannya. Walau bagaimanapun, jika spesifikasi perkakasan anda boleh mengendalikannya dan anda menyukai pratonton, anda boleh mendayakannya. Bagaimana untuk mendayakan pratonton lakaran kecil bar tugas dalam Windows 11? 1. Menggunakan apl Tetapan ketik kekunci dan klik Tetapan. Windows klik Sistem dan pilih Perihal. Klik Tetapan sistem lanjutan. Navigasi ke tab Lanjutan dan pilih Tetapan di bawah Prestasi. Pilih "Kesan Visual"

Paparkan panduan penskalaan pada Windows 11 Paparkan panduan penskalaan pada Windows 11 Sep 19, 2023 pm 06:45 PM

Kita semua mempunyai pilihan yang berbeza apabila ia berkaitan dengan penskalaan paparan pada Windows 11. Sesetengah orang suka ikon besar, ada yang suka ikon kecil. Walau bagaimanapun, kita semua bersetuju bahawa mempunyai penskalaan yang betul adalah penting. Penskalaan fon yang lemah atau penskalaan berlebihan imej boleh menjadi pembunuh produktiviti sebenar apabila bekerja, jadi anda perlu tahu cara menyesuaikannya untuk memanfaatkan sepenuhnya keupayaan sistem anda. Kelebihan Zum Tersuai: Ini adalah ciri yang berguna untuk orang yang mengalami kesukaran membaca teks pada skrin. Ia membantu anda melihat lebih banyak pada skrin pada satu masa. Anda boleh membuat profil sambungan tersuai yang digunakan hanya pada monitor dan aplikasi tertentu. Boleh membantu meningkatkan prestasi perkakasan kelas rendah. Ia memberi anda lebih kawalan ke atas perkara yang terdapat pada skrin anda. Cara menggunakan Windows 11

10 Cara untuk Melaraskan Kecerahan pada Windows 11 10 Cara untuk Melaraskan Kecerahan pada Windows 11 Dec 18, 2023 pm 02:21 PM

Kecerahan skrin adalah bahagian penting dalam menggunakan peranti pengkomputeran moden, terutamanya apabila anda melihat skrin untuk jangka masa yang lama. Ia membantu anda mengurangkan ketegangan mata, meningkatkan kebolehbacaan dan melihat kandungan dengan mudah dan cekap. Walau bagaimanapun, bergantung pada tetapan anda, kadangkala sukar untuk mengurus kecerahan, terutamanya pada Windows 11 dengan perubahan UI baharu. Jika anda menghadapi masalah melaraskan kecerahan, berikut ialah semua cara untuk mengurus kecerahan pada Windows 11. Cara Menukar Kecerahan pada Windows 11 [10 Cara Diterangkan] Pengguna monitor tunggal boleh menggunakan kaedah berikut untuk melaraskan kecerahan pada Windows 11. Ini termasuk sistem desktop menggunakan monitor tunggal serta komputer riba. Jom mulakan. Kaedah 1: Gunakan Pusat Tindakan Pusat Tindakan boleh diakses

Bagaimana untuk Membetulkan Kod Ralat Pengaktifan 0xc004f069 dalam Pelayan Windows Bagaimana untuk Membetulkan Kod Ralat Pengaktifan 0xc004f069 dalam Pelayan Windows Jul 22, 2023 am 09:49 AM

Proses pengaktifan pada Windows kadangkala mengambil giliran secara tiba-tiba untuk memaparkan mesej ralat yang mengandungi kod ralat ini 0xc004f069. Walaupun proses pengaktifan adalah dalam talian, beberapa sistem lama yang menjalankan Windows Server mungkin mengalami masalah ini. Lakukan semakan awal ini dan jika ia tidak membantu anda mengaktifkan sistem anda, lompat ke penyelesaian utama untuk menyelesaikan isu tersebut. Penyelesaian – Tutup mesej ralat dan tetingkap pengaktifan. Kemudian, mulakan semula komputer anda. Cuba semula proses pengaktifan Windows dari awal lagi. Betulkan 1 – Aktifkan dari Terminal Aktifkan sistem Windows Server Edition dari terminal cmd. Peringkat – 1 Semak Versi Pelayan Windows Anda perlu menyemak jenis W yang anda gunakan

See all articles