1. 程式人生 > 程式設計 >php如何用PDO操作大資料物件

php如何用PDO操作大資料物件

目錄

    什麼是大資料物件

    “大”通常意味著“大約 4kb 或以上”,儘管某些資料庫在資料達到“大”之前可以輕鬆地處理多達 32kb 的資料。大物件本質上可能是文字或二進位制形式的,我們在 PDOStatement::bindParam() 或 PDOStatement::bindColumn() 呼叫中使用 PDO::PARAM_LOB 型別碼可以讓 PDO 使用大資料型別。PDO::PARAM_LOB 告訴 PDO 作為流來對映資料,以便能使用 php Streams API 來操作。

    對於 mysql 來說,將欄位型別設定為 blob 即是大物件格式的欄位。而在 bindParam() 或 bindColumn() 時,指定欄位的引數為 PDO::PARAM_LOB 型別,就可以直接以控制代碼形式獲得這個物件裡面的內容,就像 fopen() 一樣地繼續對它進行操作。

    CREATE TABLE `zy_blob` (
      `id` int(11) NOT NULL AUTO_INCREMENT,`attach` longblob,PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

    這是我們測試用的一個數據表,將 attach 欄位設定為了 longblob 型別,也就是比較大的 blob 型別,這樣我們就可以儲存更多地資訊。畢竟現在的圖片或檔案隨隨便便就是輕鬆地幾m或幾十m起步的,我們直接使用最大的 blob 型別來進行簡單地測試。tinyblob 的大小為 255 位元組,blob 型別的大小為 65k ,mediumblob 為 16M ,longblob 為 4G 。

    直接操作大資料物件會怎麼樣?

    我們先來簡單地直接操作大資料物件,看看是什麼樣的結果。

    $stmt = $pdo->prepare("insert into zy_blob (attach) values (?)");
    $fp = fopen('4960364865db53dcb33bcf.rar','rb');
    $stmt->execute([$fp]);
    
    $stmt = $pdo->query("select attach from zy_blob where id=1");
    $file = $stmt->fetch(PDO::FETCH_ASSOC);
    print_r($file); 
    // Array
    // (
    //     [attach] => Resource id #6
    // )

    在這段程式碼中,我們沒有繫結欄位,然後直接將 fopen() 開啟的檔案儲存到 blob 欄位中。可以看出,在資料庫中,blob 相關的欄位只是存程式設計客棧儲了 Resource id #6 這樣的字串。也就是說,在不做任何處理的情況下,$fp 控制代碼被強制轉換成了字串型別,而控制代碼型別被強轉的結果就是隻會輸出一個資源ID,而 blob 也只是和字元型別的欄位一樣記錄了這個字串而已。

    正確的姿勢

    接下來我們來看看正確的姿勢,也就是通過 bindParam() 來插入資料,通過 bindColumn() 來讀取資料。

    $stmt = $pdo->prepare("insert into zy_blob (attach) values (?)");
    
    $fp = fopen('4960364865db53dcb33bcf.rar','rb');
    
    $stmt->bindParam(1,$fp,PDO::PARAM_LOB); // 繫結引數型別為 PDO::PARAM_LOB
    $stmt->execute();
    
    $stmt = $pdo->prepare("swww.cppcns.comelect attach from zy_blob where id=2");
    // // $file = $stmt->fetch(PDO::FETCH_ASSOC);
    // // print_r($file); // 空的
    $stmt->execute();
    $stmt->bindColumn(1,$file,PDO::PARAM_LOB); // 繫結一列到一個 PHP 變數
    $stmt->fetch(PDO::FETCH_BOUND); // 指定獲取方式,返回 TRUE 且將結果集中的列值分配給通過 PDOStatement::bindParam() 或 PDOStatement::bindColumn() 方法繫結的 PHP 變數
    print_r($file); // 二進位制亂碼內容
    $fp = fopen('a.rar','wb');
    fwrite($fp,www.cppcns.com $file);

    總結

    大資料物件操作的究竟是什麼呢?其實就是程式設計客棧我們平常要儲存的大檔案。我們將這些檔案以二進位制流的方式讀取到程式後,再將它們儲存在資料庫的欄位中。想想我們平常開發用到的最多的圖片儲存就可以用這個來做。但是,此處可以劃重點了,我們更加推薦的還是將檔案直接儲存在檔案目錄中,而資料庫中程式設計客棧只儲存它們的路徑就可以了。資料庫資源是寶貴的,表越大越不利於優化,而且資料庫本身還有快取機制,浪費它的資源來儲存這種大型的檔案其實是得不償失的。當然,如果有某些特殊的需要,比如一些私密檔案不想直接在硬碟檔案目錄中儲存,或者做為臨時的跨伺服器儲存方案都是可以的。

    在現代開發中,相信你的公司也不會吝嗇到不去買一個雲端儲存(七牛、upyun、阿里雲OSS)。它們不僅僅是能夠做為一個儲存器、網盤,而是有更多的功能,比如圖片的裁剪、水印,贈送的 CDN 、頻寬 、 流量之類的,總之,現代的儲存大家還是儘量上雲吧,即使是個人開發,也有不少廠商會提供小流量小資料量情況下的免費使用,這個都比我們自己來要方便很多。

    測試程式碼

    參考文件:

    https://www.php.net/manual/zh/pdo.lobs.php

    以上就是php如何用PDO操作大資料物件的詳細內容,更多關於php 用PDO操作大資料物件的資料請關注我們其它相關文章!