Làm cách nào để kiểm tra xem PHP đã được biên dịch với phiên bản UNICODE của API Win32 chưa?


10

Điều này có liên quan đến bài viết Stack Overflow này:

global () không thể tìm thấy tên tệp có ký tự đa nhân trên Windows?

Tôi đang gặp vấn đề với PHP và các tệp có các ký tự đa nhân trên Windows. Đây là trường hợp thử nghiệm của tôi:

print_r(scandir('./uploads/')); 
print_r(glob('./uploads/*'));

Đầu ra đúng trên máy chủ UNIX từ xa:

Array
(
    [0] => .
    [1] => ..
    [2] => filename-äöü.jpg
    [3] => filename.jpg
    [4] => test이test.jpg
    [5] => имя файла.jpg
    [6] => פילענאַמע.jpg
    [7] => 文件名.jpg
)
Array
(
    [0] => ./uploads/filename-äöü.jpg
    [1] => ./uploads/filename.jpg
    [2] => ./uploads/test이test.jpg
    [3] => ./uploads/имя файла.jpg
    [4] => ./uploads/פילענאַמע.jpg
    [5] => ./uploads/文件名.jpg
)

Đầu ra không chính xác cục bộ trên Windows:

Array
(
    [0] => .
    [1] => ..
    [2] => ??? ?????.jpg
    [3] => ???.jpg
    [4] => ?????????.jpg
    [5] => filename-äöü.jpg
    [6] => filename.jpg
    [7] => test?test.jpg
)
Array
(
    [0] => ./uploads/filename-äöü.jpg
    [1] => ./uploads/filename.jpg
)

Đây là một đoạn trích có liên quan từ câu trả lời tôi chọn chấp nhận (đây thực sự là một trích dẫn từ một bài báo đã được đăng trực tuyến hơn 2 năm trước):

Từ các bình luận về bài viết này: http://www.rooftopsolutions.nl/blog/filesystem-encoding-and-php

Đầu ra từ cài đặt PHP của bạn trên Windows rất dễ giải thích: bạn đã cài đặt phiên bản PHP sai và sử dụng phiên bản không được biên dịch để sử dụng phiên bản Unicode của API Win32. Vì lý do này, các cuộc gọi hệ thống tệp được PHP sử dụng sẽ sử dụng API "ANSI" cũ và do đó, các thư viện C / C ++ được liên kết với phiên bản PHP này trước tiên sẽ cố gắng chuyển đổi chuỗi PHP được mã hóa UTF-8 thành "ANSI" cục bộ codepage được chọn trong môi trường chạy (xem lệnh CHCP trước khi khởi động PHP từ cửa sổ dòng lệnh)

Phiên bản Windows của bạn CÓ VẤN ĐỀ NHẤT KHÔNG chịu trách nhiệm về điều kỳ lạ này. Trên thực tế, đây là phiên bản PHP của BẠN không được biên dịch chính xác và sử dụng phiên bản ANSI API Win32 kế thừa (để tương thích với các phiên bản Windows 95/98 kế thừa có hỗ trợ hệ thống tệp trong kernel thực sự không có trực tiếp hỗ trợ Unicode, nhưng đã sử dụng lớp chuyển đổi bên trong để chuyển đổi Unicode sang bảng mã ANSI cục bộ trước khi sử dụng phiên bản API ANSI thực tế).

Biên dịch lại PHP bằng tùy chọn trình biên dịch để sử dụng phiên bản UNICODE của API Win32 (ngày nay phải là mặc định và luôn luôn là mặc định cho PHP được cài đặt trên máy chủ KHÔNG BAO GIỜ là Windows 95 hoặc Windows 98 ...)

Tôi không thể xác nhận liệu đây có phải là vấn đề của tôi hay không. Tôi đã sử dụng phpinfo()và không tìm thấy bất cứ điều gì thú vị, nhưng tôi không chắc chắn những gì cần tìm kiếm. Tôi đã sử dụng XAMPP để cài đặt dễ dàng, vì vậy tôi thực sự không chắc chắn chính xác cách nó được cài đặt.

Tôi đang sử dụng Windows 7, 64 bit - vì vậy hãy tha thứ cho sự thiếu hiểu biết của tôi, nhưng tôi thậm chí không chắc liệu "Win32" có liên quan ở đây không. Làm cách nào để kiểm tra xem phiên bản PHP hiện tại của tôi đã được biên dịch với cấu hình được đề cập ở trên chưa?

  • Phiên bản PHP : 5.3.8
  • Hệ thống : Windows NT WES-PC 6.1 build 7601 (Gói dịch vụ Windows 7 Home Premium Edition 1) i586
  • Ngày xây dựng : 23 tháng 8 năm 2011 11:47:20
  • Trình biên dịch : MSVC9 (Visual C ++ 2008)
  • Kiến trúc : x86
  • Cấu hình lệnh : cscript /nologo configure.js "--enable-snapshot-build" "--disable-isapi" "--enable-debug-pack" "--disable-isapi" "--without-mssql" "--without-pdo-mssql" "--without-pi3web" "--with-pdo-oci=D:\php-sdk\oracle\instantclient10\sdk,shared" "--with-oci8=D:\php-sdk\oracle\instantclient10\sdk,shared" "--with-oci8-11g=D:\php-sdk\oracle\instantclient11\sdk,shared" "--enable-object-out-dir=../obj/" "--enable-com-dotnet" "--with-mcrypt=static" "--disable-static-analyze"

Trong trường hợp có liên quan hoặc tiết lộ bất kỳ thông tin hữu ích nào, đây là ảnh chụp màn hình của tôi phpinfo()(phần mb chuỗi ):

Ảnh chụp màn hình phpinfo

Làm cách nào để tìm hiểu xem bản cài đặt PHP của tôi có được "biên dịch với phiên bản UNICODE của Win32 API" không? (và điều đó thực sự có ý nghĩa gì không?)


5
Nâng cao vì Wesley phải coi chừng nhau.
Wesley

Bạn đã làm bất cứ điều gì trong kịch bản của bạn liên quan đến mã hóa? Tôi đã đối diện với vấn đề này với cài đặt win7-64 của tôi! Php sẽ đọc các ô và tất cả những thứ đó và chương trình di sản tào lao mà tôi đang giao tiếp với giờ giải lao khi có được những thứ đó.
Chris K

Xin lỗi để bảo lãnh cho câu hỏi này, tôi chỉ không nhận được câu trả lời nhanh chóng và bẩn thỉu mà tôi hy vọng, và cuối cùng đã ngừng phát triển dự án này trên Windows. Tôi sẽ sớm cài đặt PHP 5.4 cục bộ (trên windows) để câu hỏi có thể không còn giá trị đối với tôi nữa, nếu có ai muốn đề xuất một câu trả lời được chấp nhận thì tôi đều nghe thấy. Trong khi đó, upvote và cảm ơn tất cả xung quanh.
Wesley Murch

Câu trả lời:


3

Tôi nghĩ bạn nên tải xuống một tệp nhị phân chính thức từ kho lưu trữ PHP Windows và cài đặt nó (lưu ý đường dẫn cài đặt).

Sau đó, bạn sẽ cần phải cấu hình apache để sử dụng nhị phân mới thay vì cái mà nó mang theo mặc định. Nó đơn giản:

  • Tìm httpd.conftệp của bạn trong thư mục WAMP (một cái gì đó như C: \ wamp \ bin \ apache \ ApacheXXX \ conf \ httpd.conf) - cũng có thể đi qua khay.

  • Ok, bây giờ bạn đã tìm thấy nó xác định vị trí khớp chuỗi LoadModule php5_module

  • Tốt, chỉ cần thay thế dòng này bằng dòng mới của bạn php5_moduletrong c: /php/php5apache2_2.dll (bạn đã lưu đường dẫn cài đặt!). Kết quả trong một cái gì đó nhưLoadModule php5_module "c:/php/php5apache2_2.dll"

Voila. Đặt lại máy chủ wamp và kiểm tra ứng dụng của bạn với phiên bản php build mới nhất dành riêng cho windows.

Tôi không chắc điều này sẽ giải quyết vấn đề của bạn nhưng chắc chắn là một cách thực sự để đi. Nếu bạn gặp vấn đề về thiết lập php, hãy đọc bài viết này .

Chúc may mắn!


2

Có vẻ như câu hỏi này đã xuất hiện được một thời gian và liệu php có được biên dịch bằng cờ unicode không ảnh hưởng đến hỗ trợ unicode của nó hay không, nhưng nếu bạn cần xác định xem một hình ảnh PE cụ thể có được biên dịch theo phiên bản Unicode của API Windows, bạn có thể sử dụng dumpbinđể kiểm tra nhập khẩu kernel32.dll được sử dụng. Đây không phải là chính xác một cái gì đó tôi sẽ làm một cách thực tế, nhưng trong một tình huống khó khăn, có thể làm việc cho chẩn đoán.

Ví dụ, một tệp thực thi Unicode có thể liệt kê:

               4C CreateFileMappingW
               45 CreateDirectoryW
               33 CompareStringW
              12E GetCurrentDirectoryW
               AF ExpandEnvironmentStringsW
              2F0 SetFileAttributesW

lưu ý số lượng hàm kết thúc bằng W, aka Wide cho các ký tự unicode.

Đối với tệp thực thi ANSI hoặc DLL, bạn có thể thấy một cái gì đó gần hơn với:

              30A SetCurrentDirectoryA
              15E GetFileAttributesA
              171 GetLastError
               4B CreateDirectoryA
              319 SetFileAttributesA

với hầu hết các hàm kết thúc bằng A, chúng ta có thể thấy tệp thực thi rất có thể được biên dịch bằng cờ ANSI.


2

Đây là một số mã tôi đã làm việc để xử lý một mbstringvấn đề tôi đang gặp phải. Tôi đã kết thúc việc lặp đi lặp lại qua mọi kết hợp mã hóa và tùy chọn cho đến khi một trong số chúng trình bày kết quả đầu ra tôi cần. Tôi có cảm giác loại thủ tục này có thể giúp bạn tìm ra câu trả lời mà bạn đang tìm kiếm.

Đừng dựa vào tài liệu , như trong trường hợp của tôi, kết quả không như tôi nghĩ các tùy chọn và mã hóa sẽ làm. Tôi nhớ lại trong thử nghiệm của mình, tôi sẽ nhận được các hình chữ nhật ,?, Và những thứ như A ~. Kiểm tra của tôi là chính xác như của bạn, print_rthông tin. Trong trường hợp của tôi, tập lệnh của tôi đang nhập thông tin khách hàng và bán hàng vào Quickbooks, không thể xử lý UTF-8. (Bản thân QB không thể hoặc Trình điều khiển QODBC không thể) Tildes, graves và umlats là không thể.

setlocale(LC_CTYPE, 'en_US.UTF-8');
$xmlstr=file_get_contents($file);           
// convert character encoding to get rid of accents, etc
// see http://www.php.net/manual/en/function.mb-detect-encoding.php#89915
// note that unlike ASCII//TRANSLIT and ASCII//TRANSLIT//IGNORE do not work
// in windows 7.
$xmlstr=iconv('UTF-8', 'ASCII//IGNORE', $xmlstr);   

Liên kết đó ở trên là http://www.php.net/manual/en/feft.mb-detect-encoding.php#89915 và nếu Google tìm thấy bạn ở đây, chắc chắn hãy đọc nó.


1

Tôi tin rằng bạn sẽ muốn kiểm tra xem PHP đã được biên dịch bằng mbopes chưa (hoặc đã cài đặt và kích hoạt mô-đun mbopes nếu bạn đang sử dụng các mô-đun). Có tiện ích mở rộng được kích hoạt sẽ giải quyết vấn đề của bạn. Trang này sẽ cho bạn biết mọi thứ bạn cần biết để làm cho nó hoạt động.


Cảm ơn lời đề nghị, nhưng tôi tin rằng mbopes được cài đặt chính xác. Tôi đã thêm một ít thông tin liên quan đến điều này vào cuối bài viết của tôi. Tôi quan tâm nhiều hơn đến việc tìm hiểu về các ý kiến ​​tôi đã trích dẫn từ bài viết "Phiên bản PHP của BẠN không được biên dịch chính xác và sử dụng phiên bản ANSI API của Win32" , cách tìm hiểu xem đây có phải là trường hợp không, và điều này có liên quan hay không.
Wesley Murch

Tôi không nghĩ rằng hỗ trợ unicode trong PHP có liên quan nhiều đến hỗ trợ unicode trong API mà PHP sử dụng để thực hiện công việc của mình. Tôi nghi ngờ cái sau là vấn đề chứ không phải cái trước. (Xin lỗi vì tôi không có câu trả lời cho vấn đề này; Tôi chán ghét việc PHP hoàn toàn khủng khiếp như thế nào sau khi thử các ngôn ngữ lành mạnh để tôi không có nhiều kinh nghiệm với nó).
gparent
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.