本文目錄一覽:
js閉包和PHP閉包的區別
1 什麼是閉包
php:你跟我聊閉包之前啊,首先來聊聊 匿名函數(Anonymous function)下面就是一個匿名函數的栗子,匿名函數 顧名思義就是沒有名字啊。。
(PHP在引入閉包之前,也有一個可以創建匿名函數的函數:create function,但是代碼邏輯只能寫成字符串,這樣看起來很晦澀並且不好維護,所以很少有人用。)本人沒有驗證~~
$func = function(){
}; //帶結束符(一定要帶)
實現閉包
將匿名函數在普通函數中當做參數傳入,也可以被返回。這就實現了一個簡單的閉包。
(閉包可以保存所在代碼塊上下文的一些變量和值。PHP在默認情況下,匿名函數不能調用所在代碼塊的上下文變量,而需要通過使用use關鍵字。所以下面的一段函數會報錯 undefined variable a )
function add($a)
{ $a = $a; $fun1 = function ($b=2)
{ echo $a+$b; };
return $fun1; }
$fun1 = add(21);
$fun1(6);
如果想使用 $a 怎麼辦。php 是見招拆招啊。 關鍵字 use:
function add($a)
{ $a = $a; $fun1 = function ($b=2) use ($a) //只需要一個use($a)
{ echo $a+$b; };
return $fun1; }
$fun1 = add(21);
$fun1(6); //27
那麼能否在匿名函數中改變上下文的 變量呢 來做個試驗吧
function add($a) { // $a = $a; $fun1 = function ($b=2) use ($a) { echo $a; $a++; }; $fun1(); echo $a; }
$fun1 = add(21);
//2121 哦 很遺憾 傳值是不行的
那來試試 傳引用吧
function add($a) { // $a = $a; $fun1 = function ($b=2) use ($a) { echo $a; $a++; }; $fun1(); echo $a; }
$fun1(6); //2122 哦 可以的
使用use 關鍵字匿名函數就可以引用上下文的變量了。如果將匿名函數返回給外界,匿名函數會保存use所引用的變量,而外界則不能得到這些變量,這樣形成‘閉包’這個概念可能會更清晰一些。(也就是說 use 所引用的變量 會一直保存在內存中,直到顯示銷毀 這是閉包的一大特點)
javascript:你們php弱爆了。我們js可以直接調用 函數外部的變量。來嘮嘮js的閉包吧。
先來聊聊 js的變量作用域吧。1 全局變量,2局部變量(var vname)
阮一峰前輩說:js的閉包可以簡單的理解為,能夠獲取函數外部的變量的函數,就叫閉包。
一是讀取函數內部的變量,
二是讓這些變量的值保存在內存中,實現數據共享
閉包就是能夠讀取其他函數內部變量的函數。
由於閉包會使得函數中的變量都被保存在內存中,內存消耗很大,所以不能濫用閉包,否則會造成網頁的性能問題,在IE中可能導致內存泄露。解決方法是,在退出函數之前,將不使用的局部變量全部刪除。
2)閉包會在父函數外部,改變父函數內部變量的值。所以,如果你把父函數當作對象(object)使用,把閉包當作它的公用方法(Public Method),把內部變量當作它的私有屬性(private value),這時一定要小心,不要隨便改變父函數內部變量的值。
注意:::在javascript里,在函數里聲明的函數都是局部的,函數運行完後就釋放了
ECMAScript 描述:
函數定義和函數表達式位於另一個函數的函數體內。而且,這些內部函數可以訪問它們所在的外部函數中聲明的所有局部變量、參數和聲明的其他內部函數。當其中一個這樣的內部函數在包含它們的外部函數之外被調用時,就會形成閉包。也就是說,內部函數會在外部函數返回後被執行。而當這個內部函數執行時,它仍然必需訪問其外部函數的局部變量、參數以及其他內部函數。這些局部變量、參數和函數聲明(最初時)的值是外部函數返回時的值,但也會受到內部函數的影響。
js閉包函數為什麼有內存泄漏的問題存在
給你寫個簡單的例子你就明白了
例:
function a(){
var b = 1;
//閉包
(function(){
b = 2;
})();
}
a();
說明:按理來說b時屬於a中的一個局部變量,是會在調用a時創建,調用完銷毀的變量,但a中有一個閉包也就是其中的匿名函數調用了b,所以內存回收認為b是被引用的,因此在回收的時候不會釋放它。所以b一直存在內存中,而外部卻不能調用這個變量,這就產生了內存泄漏。。。。
純手打,求採納。
PHP CURL內存泄露的解決方法
PHP CURL內存泄露的解決方法
curl配置平淡無奇,長時間運行發現一個嚴重問題,內存泄露!不論用單線程和多線程都無法避免!是curl訪問https站點的時候有bug!
內存泄露可以通過linux的top命令發現,使用php函數memory_get_usage()不會發現。
經過反覆調試找到解決辦法,curl配置添加如下幾項解決問題:
複製代碼 代碼如下:
[CURLOPT_HTTPPROXYTUNNEL] = true;
[CURLOPT_SSL_VERIFYPEER] = false;
[CURLOPT_SSL_VERIFYHOST] = false;
CURLOPT_HTTPPROXYTUNNEL具體說明stackoverflow上有,直接貼原文:
Without CURLOPT_HTTPPROXYTUNNEL
Without CURLOPT_HTTPPROXYTUNNEL : You just use the proxy address/port as a destination of your HTTP request. The proxy will read the HTTP headers of your query, forward your request to the destination (with your HTTP headers) and then write the response to you.
Example steps :
1)HTTP GET / sent to 1.1.1.1 (proxy)
2)1.1.1.1 receive request and parse header for getting the final destination of your HTTP request.
3)1.1.1.1 forward your query and headers to (destination in request headers).
4)1.1.1.1 write back to you the response receive from
With CURLOPT_HTTPPROXYTUNNEL
With CURLOPT_HTTPPROXYTUNNEL : You ask the proxy to open a direct binary connection (like HTTPS, called a TCP Tunnel) directly to your destination by doing a CONNECT HTTP request. When the tunnel is ok, the proxy write you back a HTTP/1.1 200 Connection established. When it received your browser start to query the destination directly : The proxy does not parse HTTP headers and theoretically does not read tunnel datas, it just forward it, thats why it is called a tunnel !
Example steps :
1)HTTP CONNECT sent to 1.1.1.1
2)1.1.1.1 receive HTTP CONNECT and get the ip/port of your final destination (header field of HTTP CONNECT).
3)1.1.1.1 open a TCP Socket by doing a TCP handshake to your destination 2.22.63.73:80 (ip/port of ).
4)1.1.1.1 Make a tunnel by piping your TCP Socket to the TCP Socket opened to 2.22.63.73:80and then write you back HTTP/1.1 200 Connection established witch means that your client can now make your query throw the TCP Tunnel (TCP datas received will be transmited directly to server and vice versa). ;
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/301925.html