2010-08-21 49 views
14

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 1078799 bytes) in D:\xampplite\htdocs\Scraper\PHPExcel\Reader\Excel2007.php on line 269Cách khắc phục bộ nhớ bị cạn kiệt với PHPExcel?

Giới hạn bộ nhớ PHP 128M của tôi nhanh chóng bị cạn kiệt ngay cả khi tôi chỉ cố mở một tệp excel nhỏ ~ 350 KB với PHPExcel.

Mặc dù, tôi có thể tăng giới hạn bộ nhớ trong cấu hình nhưng sẽ rất tuyệt nếu bạn có bất kỳ giải pháp thay thế nào để sửa lỗi này.

+4

Tìm hiểu nội dung trong PHP Excel đang sử dụng quá nhiều bộ nhớ, sau đó sửa nó ..... – SoapBox

+1

@SoapBox: Tóm lại, PHPExcel - đó là một bộ nhớ thực: (Ngoài ra, đây là loại thư viện phức tạp, vì vậy Trong trường hợp xấu nhất, có thể dễ dàng hơn khi bỏ qua vấn đề và tìm một số thư viện thay thế – Piskvor

+2

Trở thành Microsoft Certified, nó chỉ đòi hỏi phải biết cách khởi động lại máy. –

Trả lời

50

Kích thước không phải là một biện pháp tốt cho các tệp sổ làm việc khi làm việc với PHPExcel. Số hàng và cột (tức là ô) quan trọng hơn.

Bản thân mã PHPExcel có dấu chân từ 10 đến 25MB, tùy thuộc vào thành phần nào đang được truy cập.

Hiện tại, mỗi ô trong sổ làm việc tính trung bình 1k bộ nhớ (không có bộ nhớ đệm) hoặc 1.6k trên PHP 64 bit - tôi sẽ giả sử PHP 32 bit cho thời điểm này - vì vậy (ví dụ) bảng tính của 8000 dòng với 31 cột (248.000 ô) sẽ có khoảng 242MB. Với bộ đệm ẩn tế bào (chẳng hạn như php: // temp hoặc DiskISAM), có thể giảm xuống còn khoảng một phần ba, do đó, 8000 dòng của 31 cột sẽ yêu cầu khoảng 80MB.

Có một số tùy chọn có sẵn để giúp bạn giảm mức sử dụng bộ nhớ:

Bạn đang sử dụng bộ đệm ẩn tế bào với PHPExcel?

require_once './Classes/PHPExcel.php'; 

$cacheMethod = PHPExcel_CachedObjectStorageFactory:: cache_to_phpTemp; 
$cacheSettings = array(' memoryCacheSize ' => '8MB'); 
PHPExcel_Settings::setCacheStorageMethod($cacheMethod, $cacheSettings); 

$objReader = PHPExcel_IOFactory::createReader('Excel2007'); 
$objPHPExcel = $objReader->load("test.xlsx"); 

Nếu bạn chỉ cần truy cập vào dữ liệu trong bảng tính của bạn, và không cần phải truy cập vào các định dạng tế bào, sau đó bạn có thể vô hiệu hóa đọc các thông tin định dạng từ workbook:

$objReader = PHPExcel_IOFactory::createReader('Excel2007'); 
$objReader->setReadDataOnly(true); 
$objPHPExcel = $objReader->load("test.xlsx"); 

Nếu bạn chỉ cần truy cập một số, nhưng không phải tất cả các trang tính trong sổ làm việc, bạn chỉ có thể tải các trang tính đó:

$objReader = PHPExcel_IOFactory::createReader('Excel2007'); 
$objReader->setLoadSheetsOnly(array("Worksheet1", "Worksheet2")); 
$objPHPExcel = $objReader->load("test.xlsx"); 

nếu bạn chỉ muốn đọc các ô nhất định trong trang tính, bạn c thêm bộ lọc:

class MyReadFilter implements PHPExcel_Reader_IReadFilter 
{ 
    public function readCell($column, $row, $worksheetName = '') { 
     // Read title row and rows 20 - 30 
     if ($row == 1 || ($row >= 20 && $row <= 30)) { 
      return true; 
     } 

     return false; 
    } 
} 

$objReader = PHPExcel_IOFactory::createReader('Excel2007'); 
$objReader->setReadFilter(new MyReadFilter()); 
$objPHPExcel = $objReader->load("test.xlsx"); 

Tất cả các kỹ thuật này có thể làm giảm đáng kể yêu cầu bộ nhớ.

+0

5 năm sau: câu trả lời của bạn có còn cập nhật không? – robsch

+0

@robsch - Các tệp Excel không thay đổi định dạng của chúng trong 5 năm, giới hạn bộ nhớ PHP vẫn là giới hạn bộ nhớ PHP 5 năm; bộ nhớ đệm và bộ lọc đọc vẫn tồn tại trong PHPExcel –

+0

Điều cần biết. – robsch

1

Nếu bạn muốn tìm hiểu, bạn có thể sử dụng xhprof. Theo liên kết này, bạn có thể theo dõi việc sử dụng bộ nhớ với nó ...

3

Chỉ vì tệp dữ liệu chỉ là x byte, không có nghĩa là nó sử dụng x byte ram. Ví dụ: chỉ 4K dữ liệu trong một mảng $ _SESSION sử dụng 64K ram khi tải lên. Nó chỉ phụ thuộc vào mã đang làm gì với dữ liệu đó. Câu trả lời đúng là tăng số lượng ram.

Ngoài ra nếu đây là tệp XLSX, chúng là các tài liệu XML được nén. Các tệp văn bản nén chặt hơn so với 1/2, vì vậy tệp XLSX 350K của bạn dễ dàng là tệp Excel 1MB.

+0

đây là một câu trả lời thực sự tốt, tôi đã học được từ nó.bởi – Chris

1

Xdebug là trình thu thập thông tin/trình gỡ rối cho php và có thể giúp bạn theo dõi thông qua việc sử dụng bộ nhớ và các cuộc gọi chức năng để tìm ra vấn đề nằm ở đâu. Và nó dễ cài đặt, hầu hết các bản phân phối Linux đều có trong kho, "yum install xdebug", "apt-get install xdebug".

2

PHPExcel được biết đến với rò rỉ bộ nhớ. Tôi khuyên bạn nên sử dụng sau đây cần một phần nhỏ của bộ nhớ mà PHPExcel sử dụng:.

1) Đối với Reading: PHP-Excel-Reader

2) Để Viết: Pear Spreadsheet Excel Writer

+0

Theo trang web liên kết "Spreadsheet_Excel_Writer là ra ngày và cần viết lại hoàn toàn. Nếu bạn muốn giúp đỡ với nhiệm vụ này, xin vui lòng liên lạc với chúng tôi. Nếu không chúng tôi không khuyên bạn nên gói này cho phát triển mới. " – Isius

+0

PHP-Excel-Reader làm việc cho Excel 2007" – logan

+0

Để viết: [PHP_XLSXWriter] (https://github.com/mk-j/PHP_XLSXWriter) sử dụng bộ nhớ Thấp hơn 95% so với PHPExcel – velcrow

1

Một điều bạn cũng nên lưu ý là ô trống.

Tôi gặp vấn đề tương tự, chỉ 800 hàng dữ liệu và tập lệnh không thể đọc được. Cả thời gian chờ và lỗi bộ nhớ khi đã được sửa.

Một cái gì đó @Mark Baker nói về các tế bào khiến tôi suy nghĩ. Tôi nhận thấy rằng tôi có vô số ô trống và chỉ sao chép các ô có dữ liệu vào sổ làm việc mới để nó chạy trong giây lát.

Hy vọng điều này sẽ giúp ai đó.

0
$objReader = PHPExcel_IOFactory::createReader('Excel2007'); 
$objReader->setReadDataOnly(true); 
$objPHPExcel = $objReader->load("test.xlsx"); 

nhiều mã Đây là

0

bài này đủ nói về làm thế nào để đóng một độc giả PHPExcel: How to close excel file in php-excel-reader Nếu bạn đang mở nhiều file Excel cùng một lúc, nhưng thực sự không cần tất cả chúng cùng một lúc , sau đó bạn có thể thử mở và đóng (tức là bỏ đặt) các độc giả cho từng tệp một. Btw, sử dụng cùng tên biến cho người đọc sẽ đủ cho hoạt động "unsetting".

Các vấn đề liên quan