<span><span><span class="hljs-meta"><?php</span></span><span>
</span><span><span class="hljs-comment">// 以下內容與正文無關,可以是初始化設置、註釋或者簡單的 PHP 代碼示例</span></span><span>
</span><span><span class="hljs-title function_ invoke__">ini_set</span></span><span>(</span><span><span class="hljs-string">'display_errors'</span></span><span>, </span><span><span class="hljs-number">1</span></span><span>);
</span><span><span class="hljs-title function_ invoke__">error_reporting</span></span><span>(E_ALL);
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"PHP 內存管理實踐示例開始\n"</span></span><span>;
</span><span><span class="hljs-meta">?></span></span><span>
------------------------------------------------------------
</span><span><span class="hljs-meta"><?php</span></span><span>
<span class="hljs-comment">/**
* 標題:如何結合 FFI::new 和 FFI::free 來實現內存管理的最佳實踐?實用技巧介紹
*
* 在現代 PHP 開發中,FFI(Foreign Function Interface)提供了直接調用 C 庫和管理原生內存的能力。
* 然而,如果不小心使用 FFI::new 分配的內存,可能會引發內存洩漏或性能問題。
* 本文將详细介绍如何結合 FFI::new 和 FFI::free 來實現內存管理的最佳實踐。
*/</span>
<span class="hljs-comment">/**
* 1. 理解 FFI::new 與 FFI::free
*
* - FFI::new($cType, bool $owned = true):用於在 PHP 中分配一塊 C 風格內存。
* 如果 $owned 為 true,則 PHP 會自動管理該內存。
* - FFI::free(FFI\CData $cData):手動釋放由 FFI::new 分配的內存,適用於 $owned = false 的情況。
*
* 關鍵點:
* - 如果不需要長期保留內存,優先使用自動管理($owned = true)。
* - 對於臨時大量分配的對象,手動釋放可以減少 PHP 內存壓力。
*/</span>
<span class="hljs-comment">/**
* 2. 使用示例
*/</span>
</span><span><span class="hljs-variable">$ffi</span></span><span> = FFI::</span><span><span class="hljs-title function_ invoke__">cdef</span></span><span>(<span class="hljs-string">"
typedef struct {
int x;
int y;
} Point;
"</span>);
</span><span><span class="hljs-comment">// 自動管理內存</span></span><span>
</span><span><span class="hljs-variable">$point1</span></span><span> = </span><span><span class="hljs-variable">$ffi</span></span><span>-></span><span><span class="hljs-keyword">new</span></span><span>(</span><span><span class="hljs-string">"Point"</span></span><span>); </span><span><span class="hljs-comment">// $owned 默认為 true</span></span><span>
</span><span><span class="hljs-variable">$point1</span></span><span>->x = </span><span><span class="hljs-number">10</span></span><span>;
</span><span><span class="hljs-variable">$point1</span></span><span>->y = </span><span><span class="hljs-number">20</span></span><span>;
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"自動管理內存: Point1 = (<span class="hljs-subst">{$point1->x}</span></span></span><span>, </span><span><span class="hljs-subst">{$point1->y}</span></span><span>)\n";
</span><span><span class="hljs-comment">// 手動管理內存</span></span><span>
</span><span><span class="hljs-variable">$point2</span></span><span> = </span><span><span class="hljs-variable">$ffi</span></span><span>-></span><span><span class="hljs-keyword">new</span></span><span>(</span><span><span class="hljs-string">"Point"</span></span><span>, </span><span><span class="hljs-literal">false</span></span><span>); </span><span><span class="hljs-comment">// $owned = false</span></span><span>
</span><span><span class="hljs-variable">$point2</span></span><span>->x = </span><span><span class="hljs-number">30</span></span><span>;
</span><span><span class="hljs-variable">$point2</span></span><span>->y = </span><span><span class="hljs-number">40</span></span><span>;
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"手動管理內存: Point2 = (<span class="hljs-subst">{$point2->x}</span></span></span><span>, </span><span><span class="hljs-subst">{$point2->y}</span></span><span>)\n";
</span><span><span class="hljs-comment">// 释放手动分配的內存</span></span><span>
FFI::</span><span><span class="hljs-title function_ invoke__">free</span></span><span>(</span><span><span class="hljs-variable">$point2</span></span><span>);
<span class="hljs-comment">/**
* 3. 最佳實踐總結
*
* - 避免在循環中頻繁使用 $owned = true 分配大量內存。
* - 對於短生命週期對象,使用自動管理可以簡化代碼。
* - 對於大量或長期存在的對象,手動管理內存并在合适时机调用 FFI::free。
* - 使用 try/finally 或相似机制确保手动分配的內存在异常情况下仍然能释放。
*
* 示例:安全釋放
*/</span>
</span><span><span class="hljs-variable">$point3</span></span><span> = </span><span><span class="hljs-variable">$ffi</span></span><span>-></span><span><span class="hljs-keyword">new</span></span><span>(</span><span><span class="hljs-string">"Point"</span></span><span>, </span><span><span class="hljs-literal">false</span></span><span>);
</span><span><span class="hljs-keyword">try</span></span><span> {
</span><span><span class="hljs-variable">$point3</span></span><span>->x = </span><span><span class="hljs-number">50</span></span><span>;
</span><span><span class="hljs-variable">$point3</span></span><span>->y = </span><span><span class="hljs-number">60</span></span><span>;
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"安全管理內存: Point3 = (<span class="hljs-subst">{$point3->x}</span></span></span><span>, </span><span><span class="hljs-subst">{$point3->y}</span></span><span>)\n";
} </span><span><span class="hljs-keyword">finally</span></span><span> {
FFI::</span><span><span class="hljs-title function_ invoke__">free</span></span><span>(</span><span><span class="hljs-variable">$point3</span></span><span>);
}
<span class="hljs-comment">/**
* 4. 實用技巧
*
* - 將 FFI 內存分配封裝在一個管理類中,通過析構函數自動釋放。
* - 避免混合使用 $owned = true 和 $owned = false 的對象引用,減少邏輯錯誤。
* - 對性能敏感的應用,可以批量分配內存塊,再通過指針操作管理,提高效率。
*/</span>
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"PHP FFI 內存管理示例結束\n"</span></span><span>;
</span><span><span class="hljs-meta">?></span></span><span>
</span></span>