Nhà soạn nhạc có yêu cầu phpoffice/phpspreadsheet không có Sudo không?
Tôi muốn viết Script bằng gói Phpspreadsheet. Tôi không có kinh nghiệm về php. Tôi đang cố gắng thêm tham chiếu vào tập lệnh của mình thông qua sudo composer require phpoffice/phpspreadsheet. Nhưng nó không hoạt động. tôi đang nhận được lỗi. Cài đặt không thành công, đang xóa trình soạn nhạc. json…. Nếu không biết tại sao nó không hoạt động. Bất kỳ ý tưởng? Show
lỗi chi tiết
Giải pháp tốt nhấtVì vậy, tôi nên cài đặt 9 0 1 2Giải pháp liên quanPhp – PHP ‘foreach’ thực sự hoạt động như thế nào 3 hỗ trợ lặp qua ba loại giá trị khác nhau
Sau đây, tôi sẽ cố gắng giải thích chính xác cách thức hoạt động của phép lặp trong các trường hợp khác nhau. Cho đến nay, trường hợp đơn giản nhất là các đối tượng 4, đối với các đối tượng 3 này về cơ bản chỉ là đường cú pháp cho mã dọc theo các dòng này
Đối với các lớp nội bộ, tránh các cuộc gọi phương thức thực tế bằng cách sử dụng API nội bộ về cơ bản chỉ phản ánh giao diện 7 ở cấp độ CViệc lặp lại các mảng và các đối tượng đơn giản phức tạp hơn nhiều. Trước hết, cần lưu ý rằng trong "mảng" PHP thực sự là các từ điển có thứ tự và chúng sẽ được duyệt theo thứ tự này (khớp với thứ tự chèn miễn là bạn không sử dụng thứ gì đó như 8). Điều này trái ngược với việc lặp lại theo thứ tự tự nhiên của các khóa (cách hoạt động của danh sách trong các ngôn ngữ khác) hoặc không có thứ tự xác định nào (cách hoạt động của từ điển trong các ngôn ngữ khác)Điều tương tự cũng áp dụng cho các đối tượng, vì các thuộc tính đối tượng có thể được xem như một tên thuộc tính ánh xạ từ điển (được sắp xếp) khác với các giá trị của chúng, cộng với một số xử lý khả năng hiển thị. Trong phần lớn các trường hợp, các thuộc tính đối tượng không thực sự được lưu trữ theo cách không hiệu quả này. Tuy nhiên, nếu bạn bắt đầu lặp lại một đối tượng, biểu diễn đóng gói thường được sử dụng sẽ được chuyển đổi thành một từ điển thực. Tại thời điểm đó, phép lặp của các đối tượng đơn giản trở nên rất giống với phép lặp của mảng (đó là lý do tại sao tôi không thảo luận nhiều về phép lặp đối tượng đơn giản ở đây) Càng xa càng tốt. Lặp đi lặp lại một từ điển không thể quá khó, phải không? . Có nhiều cách điều này có thể xảy ra
Vấn đề với việc cho phép sửa đổi trong quá trình lặp lại là trường hợp phần tử bạn đang bật bị xóa. Giả sử bạn sử dụng một con trỏ để theo dõi xem bạn đang ở phần tử mảng nào. Nếu phần tử này hiện được giải phóng, bạn chỉ còn lại một con trỏ lơ lửng (thường dẫn đến lỗi phân tách) Có nhiều cách khác nhau để giải quyết vấn đề này. PHP 5 và PHP 7 khác nhau đáng kể về vấn đề này và tôi sẽ mô tả cả hai hành vi sau đây. Tóm tắt là cách tiếp cận của PHP 5 khá ngu ngốc và dẫn đến tất cả các loại vấn đề về trường hợp cạnh kỳ lạ, trong khi cách tiếp cận liên quan nhiều hơn của PHP 7 dẫn đến hành vi nhất quán và dễ đoán hơn Như một sơ bộ cuối cùng, cần lưu ý rằng PHP sử dụng đếm tham chiếu và sao chép khi ghi để quản lý bộ nhớ. Điều này có nghĩa là nếu bạn "sao chép" một giá trị, bạn thực sự chỉ sử dụng lại giá trị cũ và tăng số lượng tham chiếu (refcount) của nó. Chỉ khi bạn thực hiện một số loại sửa đổi, một bản sao thực sự (được gọi là "sao chép") sẽ được thực hiện. Xem Bạn đang bị lừa dối để giới thiệu rộng rãi hơn về chủ đề này PHP5Con trỏ mảng bên trong và HashPulumMảng trong PHP 5 có một "con trỏ mảng bên trong" (IAP) chuyên dụng, hỗ trợ đúng các sửa đổi. Bất cứ khi nào một phần tử bị xóa, sẽ có kiểm tra xem IAP có trỏ đến phần tử này không. Nếu đúng như vậy, thay vào đó, nó sẽ được chuyển sang phần tử tiếp theo Trong khi 3 sử dụng IAP, có một vấn đề phức tạp khác. Chỉ có một IAP, nhưng một mảng có thể là một phần của nhiều vòng lặp 3
Để hỗ trợ hai vòng lặp đồng thời chỉ với một con trỏ mảng bên trong, 3 thực hiện các trò tai quái sau. Trước khi phần thân vòng lặp được thực thi, 3 sẽ sao lưu một con trỏ tới phần tử hiện tại và hàm băm của nó thành một giá trị cho mỗi lần truy cập 6. Sau khi thân vòng lặp chạy, IAP sẽ được đặt trở lại thành phần này nếu nó vẫn tồn tại. Tuy nhiên, nếu phần tử đã bị xóa, chúng tôi sẽ chỉ sử dụng bất cứ nơi nào IAP hiện đang ở. Kế hoạch này chủ yếu là loại hoạt động, nhưng có rất nhiều hành vi kỳ lạ mà bạn có thể thoát khỏi nó, một số trong số đó tôi sẽ chứng minh bên dướisao chép mảngIAP là một tính năng hiển thị của một mảng (được hiển thị thông qua họ hàm 7), vì những thay đổi như vậy đối với IAP được coi là sửa đổi theo ngữ nghĩa sao chép khi ghi. Thật không may, điều này có nghĩa là trong nhiều trường hợp, 3 buộc phải sao chép mảng mà nó đang lặp lại. Các điều kiện chính xác là
Nếu mảng không trùng lặp (is_ref=0, refcount=1) thì chỉ có 9 của nó được tăng lên (*). Ngoài ra, nếu sử dụng 3 theo tham chiếu, thì mảng (có khả năng trùng lặp) sẽ được chuyển thành tham chiếuHãy coi mã này là một ví dụ nơi xảy ra sự trùng lặp
Tại đây, 0 sẽ được sao chép để ngăn các thay đổi IAP trên 0 rò rỉ sang 4. Về các điều kiện trên, mảng không phải là tham chiếu (is_ref=0) và được sử dụng ở hai vị trí (refcount=2). Yêu cầu này là không may và là một yếu tố tạo tác của việc triển khai dưới mức tối ưu (không có lo ngại về sửa đổi trong quá trình lặp lại ở đây, vì vậy chúng tôi không thực sự cần sử dụng IAP ngay từ đầu)(*) Tăng 9 ở đây nghe có vẻ vô thưởng vô phạt, nhưng vi phạm ngữ nghĩa copy-on-write (COW). Điều này có nghĩa là chúng ta sẽ sửa đổi IAP của một mảng refcount=2, trong khi COW chỉ ra rằng các sửa đổi chỉ có thể được thực hiện trên các giá trị refcount=1. Vi phạm này dẫn đến thay đổi hành vi mà người dùng có thể nhìn thấy (trong khi COW thường trong suốt) vì thay đổi IAP trên mảng lặp sẽ có thể quan sát được -- nhưng chỉ cho đến khi sửa đổi không phải IAP đầu tiên trên mảng. Thay vào đó, ba tùy chọn "hợp lệ" sẽ là a) luôn trùng lặp, b) không tăng 9 và do đó cho phép mảng lặp được sửa đổi tùy ý trong vòng lặp hoặc c) hoàn toàn không sử dụng IAP ( Thứ tự thăng tiến chức vụCó một chi tiết triển khai cuối cùng mà bạn phải biết để hiểu đúng các mẫu mã bên dưới. Cách lặp "bình thường" thông qua một số cấu trúc dữ liệu sẽ trông giống như thế này trong mã giả
Tuy nhiên, 3, là một bông tuyết khá đặc biệt, chọn cách làm hơi khác một chút
Cụ thể, con trỏ mảng đã được di chuyển về phía trước trước khi thân vòng lặp chạy. Điều này có nghĩa là trong khi thân vòng lặp đang hoạt động trên phần tử 8, thì IAP đã ở phần tử 9. Đây là lý do tại sao các mẫu mã hiển thị sửa đổi trong quá trình lặp lại sẽ luôn 0 phần tử tiếp theo, thay vì phần tử hiện tạiví dụ. Các trường hợp thử nghiệm của bạnBa khía cạnh được mô tả ở trên sẽ cung cấp cho bạn ấn tượng gần như đầy đủ về các đặc điểm riêng của việc triển khai 3 và chúng ta có thể chuyển sang thảo luận về một số ví dụHành vi của các trường hợp thử nghiệm của bạn rất đơn giản để giải thích tại thời điểm này
ví dụ. Ảnh hưởng của function iterate($arr) { foreach ($arr as $v) {} } $outerArr = [0, 1, 2, 3, 4]; iterate($outerArr); 7 trong foreachMột cách hay để chỉ ra các hành vi trùng lặp khác nhau là quan sát hành vi của hàm 6 bên trong vòng lặp 3. Hãy xem xét ví dụ này
Ở đây bạn nên biết rằng 6 là một hàm by-ref (thực ra. prefer-ref), mặc dù nó không sửa đổi mảng. Nó phải hoạt động tốt với tất cả các chức năng khác như 9, tất cả đều là phụ đề. Truyền tham chiếu phụ ngụ ý rằng mảng phải được tách biệt và do đó, 2 và 1 sẽ khác nhau. Lý do bạn nhận được 2 thay vì 3 cũng đã được đề cập ở trên. 3 tiến con trỏ mảng trước khi chạy mã người dùng, không phải sau. Vì vậy, mặc dù mã nằm ở phần tử đầu tiên, nhưng 3 đã nâng cao con trỏ đến phần tử thứ haiBây giờ hãy thử một sửa đổi nhỏ
Ở đây chúng ta có trường hợp is_ref=1 nên mảng không được sao chép (giống như trên). Nhưng bây giờ nó là một tham chiếu, mảng không còn phải được nhân đôi khi chuyển đến hàm by-ref 6. Vì vậy, 6 và 3 hoạt động trên cùng một mảng. Tuy nhiên, bạn vẫn thấy hành vi không giống nhau, do cách 3 tiến con trỏBạn có hành vi tương tự khi thực hiện lặp lại giới thiệu
Ở đây, phần quan trọng là foreach sẽ biến 2 thành is_ref=1 khi nó được lặp lại theo tham chiếu, vì vậy về cơ bản, bạn có tình huống tương tự như trênMột biến thể nhỏ khác, lần này chúng ta sẽ gán mảng cho một biến khác
Ở đây, số lần đếm lại của 2 là 2 khi vòng lặp bắt đầu, vì vậy lần đầu tiên chúng ta thực sự phải thực hiện sao chép trước. Do đó, 2 và mảng được sử dụng bởi foreach sẽ hoàn toàn tách biệt ngay từ đầu. Đó là lý do tại sao bạn có được vị trí của IAP ở bất kỳ vị trí nào trước vòng lặp (trong trường hợp này là vị trí đầu tiên)ví dụ. Sửa đổi trong quá trình lặpCố gắng giải thích cho các sửa đổi trong quá trình lặp lại là nơi bắt nguồn tất cả các rắc rối foreach của chúng tôi, vì vậy, nó phục vụ để xem xét một số ví dụ cho trường hợp này Hãy xem xét các vòng lặp lồng nhau này trên cùng một mảng (trong đó phép lặp by-ref được sử dụng để đảm bảo rằng nó thực sự giống nhau) 0Phần được mong đợi ở đây là ______69_______3 bị thiếu trong đầu ra vì phần tử ______59_______3 đã bị xóa. Điều có thể bất ngờ là vòng lặp bên ngoài dừng sau phần tử đầu tiên. Tại sao vậy? Lý do đằng sau điều này là hack vòng lặp lồng nhau được mô tả ở trên. Trước khi thân vòng lặp chạy, vị trí IAP hiện tại và hàm băm được sao lưu vào một 6. Sau thân vòng lặp, nó sẽ được khôi phục, nhưng chỉ khi phần tử vẫn tồn tại, nếu không, vị trí IAP hiện tại (bất kể nó có thể là gì) được sử dụng thay thế. Trong ví dụ trên, đây chính xác là trường hợp. Phần tử hiện tại của vòng lặp bên ngoài đã bị xóa, vì vậy nó sẽ sử dụng IAP, đã được đánh dấu là kết thúc bởi vòng lặp bên trongMột hệ quả khác của cơ chế sao lưu + khôi phục 6 là các thay đổi đối với IAP thông qua 7, v.v. thường không ảnh hưởng đến 3. Ví dụ: đoạn mã sau thực thi như thể 7 hoàn toàn không có mặt 1Lý do là, trong khi 7 tạm thời sửa đổi IAP, nó sẽ được khôi phục về phần tử foreach hiện tại sau thân vòng lặp. Để buộc 7 tạo hiệu ứng trên vòng lặp, bạn phải xóa thêm phần tử hiện tại để cơ chế sao lưu/khôi phục không thành công 2Nhưng, những ví dụ đó vẫn lành mạnh. Điều thú vị thực sự bắt đầu nếu bạn nhớ rằng khôi phục 6 sử dụng một con trỏ tới phần tử và hàm băm của nó để xác định xem nó có còn tồn tại hay không. Nhưng. Băm có xung đột và con trỏ có thể được sử dụng lại. Điều này có nghĩa là, với sự lựa chọn cẩn thận các khóa mảng, chúng ta có thể khiến 3 tin rằng một phần tử đã bị xóa vẫn tồn tại, vì vậy nó sẽ chuyển trực tiếp đến phần tử đó. Một ví dụ 3Ở đây chúng ta thường mong đợi đầu ra 4 theo các quy tắc trước đó. Làm thế nào điều xảy ra là 5 có cùng hàm băm như phần tử bị loại bỏ 6 và bộ cấp phát tình cờ sử dụng lại cùng một vị trí bộ nhớ để lưu trữ phần tử. Vì vậy, foreach kết thúc trực tiếp nhảy đến phần tử mới được chèn, do đó rút ngắn vòng lặpThay thế thực thể lặp trong vòng lặpMột trường hợp kỳ lạ cuối cùng mà tôi muốn đề cập, đó là PHP cho phép bạn thay thế thực thể được lặp lại trong vòng lặp. Vì vậy, bạn có thể bắt đầu lặp lại trên một mảng và sau đó thay thế nó bằng một mảng khác giữa chừng. Hoặc bắt đầu lặp trên một mảng và sau đó thay thế nó bằng một đối tượng 4Như bạn có thể thấy trong trường hợp này, PHP sẽ chỉ bắt đầu lặp lại thực thể khác ngay từ đầu khi sự thay thế đã xảy ra PHP7Trình vòng lặp HashtableNếu bạn vẫn còn nhớ, vấn đề chính với lặp mảng là làm thế nào để xử lý việc loại bỏ các phần tử giữa các lần lặp. PHP 5 đã sử dụng một con trỏ mảng bên trong (IAP) cho mục đích này, điều này hơi không tối ưu, vì một con trỏ mảng phải được kéo dài để hỗ trợ nhiều vòng lặp foreach đồng thời và tương tác với 7, v.v. trên đóPHP 7 sử dụng một cách tiếp cận khác, cụ thể là nó hỗ trợ tạo một số lượng tùy ý các trình vòng lặp có thể băm an toàn bên ngoài. Các trình vòng lặp này phải được đăng ký trong mảng, từ đó chúng có cùng ngữ nghĩa với IAP. Nếu một phần tử mảng bị xóa, tất cả các trình lặp hashtable trỏ đến phần tử đó sẽ được chuyển sang phần tử tiếp theo Điều này có nghĩa là 3 sẽ không còn sử dụng IAP nữa. Vòng lặp 3 sẽ hoàn toàn không ảnh hưởng đến kết quả của 6, v.v. và hành vi của chính nó sẽ không bao giờ bị ảnh hưởng bởi các chức năng như 7, v.v.sao chép mảngMột thay đổi quan trọng khác giữa PHP 5 và PHP 7 liên quan đến sao chép mảng. Bây giờ IAP không còn được sử dụng nữa, phép lặp mảng theo giá trị sẽ chỉ thực hiện gia số 9 (thay vì sao chép mảng) trong mọi trường hợp. Nếu mảng được sửa đổi trong vòng lặp 3, tại thời điểm đó sẽ xảy ra sự trùng lặp (theo copy-on-write) và 3 sẽ tiếp tục hoạt động trên mảng cũTrong hầu hết các trường hợp, thay đổi này là minh bạch và không có tác dụng nào khác ngoài hiệu suất tốt hơn. Tuy nhiên, có một trường hợp nó dẫn đến hành vi khác, cụ thể là trường hợp trước đó mảng là một tham chiếu 5Việc lặp lại theo giá trị trước đây của mảng tham chiếu là trường hợp đặc biệt. Trong trường hợp này, không xảy ra trùng lặp, vì vậy tất cả các sửa đổi của mảng trong quá trình lặp sẽ được phản ánh bởi vòng lặp. Trong PHP 7, trường hợp đặc biệt này không còn nữa. Lặp lại giá trị phụ của một mảng sẽ luôn tiếp tục hoạt động trên các phần tử ban đầu, bỏ qua mọi sửa đổi trong vòng lặp Tất nhiên, điều này không áp dụng cho phép lặp tham chiếu phụ. Nếu bạn lặp theo tham chiếu, tất cả các sửa đổi sẽ được phản ánh bởi vòng lặp. Thật thú vị, điều này cũng đúng với phép lặp giá trị phụ của các đối tượng đơn giản 6Điều này phản ánh ngữ nghĩa xử lý phụ của các đối tượng (i. e. chúng hoạt động giống như tham chiếu ngay cả trong ngữ cảnh phụ giá trị) ví dụHãy xem xét một vài ví dụ, bắt đầu với các trường hợp thử nghiệm của bạn
Nhóm ví dụ thứ hai liên quan đến hành vi của 6 dưới các cấu hình 12 khác nhau. Điều này không còn hợp lý nữa, vì 6 hoàn toàn không bị ảnh hưởng bởi vòng lặp, vì vậy giá trị trả về của nó luôn giữ nguyênTuy nhiên, chúng tôi nhận được một số thay đổi thú vị khi xem xét sửa đổi trong quá trình lặp lại. Tôi hy vọng bạn sẽ tìm thấy hành vi mới lành mạnh hơn. ví dụ đầu tiên 7Như bạn có thể thấy, vòng lặp bên ngoài không còn bị hủy bỏ sau lần lặp đầu tiên. Lý do là cả hai vòng lặp hiện có các trình vòng lặp có thể băm hoàn toàn riêng biệt và không còn bất kỳ sự lây nhiễm chéo nào của cả hai vòng lặp thông qua một IAP được chia sẻ Một trường hợp cạnh kỳ lạ khác hiện đã được khắc phục, đó là hiệu ứng kỳ lạ mà bạn nhận được khi xóa và thêm các phần tử có cùng hàm băm 8Trước đây, cơ chế khôi phục HashPulum đã chuyển ngay sang phần tử mới vì nó "trông" giống như phần tử đã xóa (do hàm băm và con trỏ xung đột). Vì chúng tôi không còn dựa vào hàm băm của phần tử cho bất kỳ thứ gì nên đây không còn là vấn đề nữa Việc sử dụng Phpspreadsheet là gì?Giới thiệu. PHPSpreadsheet là một thư viện được viết bằng PHP giúp đọc và ghi vào các loại định dạng tệp bảng tính khác nhau với sự trợ giúp của một nhóm lớp nhất định . Các định dạng khác nhau hỗ trợ bảng tính là Excel (. xlsx), Định dạng Tài liệu Mở(. ods),Bảng tínhML(.
Làm cách nào để cài đặt PHPSpreadsheet trong CodeIgniter 3?Cài đặt . Tải xuống và cài đặt CodeIgniter Sử dụng Composer để cài đặt PhpSpreadsheet vào dự án của bạn. nhà soạn nhạc yêu cầu phpoffice/phpspreadsheet Mở ứng dụng/config/config. php và đặt đường dẫn thư mục nhà cung cấp của bạn. . Sử dụng phpspreadsheet thư viện bên trong bộ điều khiển của bạn PHPOffice là gì?PHPOffice là tập hợp các thư viện PHP mã nguồn mở miễn phí để đọc và ghi tệp từ nhiều định dạng tài liệu khác nhau . Hiện tại có ba dự án liên kết với PHPOffice. PHPSpreadsheet, PHPPresentation và PHPWord.
Làm cách nào để cài đặt PhpSpreadsheet trong CentOS 7?Cài đặt . sudo apt-get cài đặt php7. 2-gd php7. 2-mbstring php7. 2-zip -y sudo apt-get cài đặt php7. 4-gd php7. 4-mbstring php7. 4-zip -y nhà soạn nhạc yêu cầu phpoffice/phpspreadsheet . '/. $writer = new PhpOffice\PhpSpreadsheet\Writer\Csv($spreadsheet); . csv'); |