Bagaimana saya bisa memeriksa apakah PHP dikompilasi dengan versi UNICODE dari Win32 API?

10

Ini terkait dengan pos Stack Overflow ini:

glob () tidak dapat menemukan nama file dengan karakter multibyte di Windows?

Saya mengalami masalah dengan PHP dan file yang memiliki karakter multibyte di Windows. Inilah kotak ujian saya:

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

Output yang benar pada server UNIX jarak jauh:

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
)

Output salah pada 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
)

Berikut kutipan yang relevan dari jawaban yang saya pilih untuk diterima (yang sebenarnya adalah kutipan dari artikel yang diposting online lebih dari 2 tahun yang lalu):

Dari komentar di artikel ini: http://www.rooftopsolutions.nl/blog/filesystem-encoding-and-php

Output dari instalasi PHP Anda di Windows mudah dijelaskan: Anda menginstal versi PHP yang salah, dan menggunakan versi yang tidak dikompilasi untuk menggunakan versi Unicode dari Win32 API. Untuk alasan ini, panggilan filesystem yang digunakan oleh PHP akan menggunakan API "ANSI" yang lama, sehingga pustaka C / C ++ yang terhubung dengan versi PHP ini pertama-tama akan mencoba mengonversi string PHP Anda yang disandikan UTF-8 menjadi lokal "ANSI" codepage dipilih di lingkungan yang berjalan (lihat perintah CHCP sebelum memulai PHP dari jendela baris perintah)

Versi Windows Anda PALING MUNGKIN TIDAK bertanggung jawab atas hal aneh ini. Sebenarnya, ini adalah versi ANDA PHP yang tidak dikompilasi dengan benar, dan yang menggunakan versi lama ANSI dari Win32 API (untuk kompatibilitas dengan versi lama 16-bit Windows 95/98 yang dukungan sistem file di kernel sebenarnya tidak memiliki direct mendukung Unicode, tetapi menggunakan lapisan konversi internal untuk mengonversi Unicode ke codepage ANSI lokal sebelum menggunakan versi ANSI API yang sebenarnya).

Kompilasi ulang PHP menggunakan opsi kompiler untuk menggunakan versi UNICODE dari Win32 API (yang seharusnya menjadi standar hari ini, dan lagi pula selalu default untuk PHP yang diinstal pada server yang TIDAK akan pernah menjadi Windows 95 atau Windows 98 ...)

Saya tidak dapat mengkonfirmasi apakah ini masalah saya atau tidak. Saya menggunakan phpinfo()dan tidak menemukan sesuatu yang menarik, tetapi saya tidak yakin apa yang harus dicari. Saya telah menggunakan XAMPP untuk instalasi yang mudah, jadi saya benar-benar tidak yakin persis bagaimana itu diinstal.

Saya menggunakan Windows 7, 64 bit - jadi maafkan ketidaktahuan saya, tapi saya bahkan tidak yakin apakah "Win32" relevan di sini. Bagaimana saya dapat memeriksa apakah versi PHP saya saat ini dikompilasi dengan konfigurasi yang disebutkan di atas?

  • Versi PHP : 5.3.8
  • Sistem : Windows NT WES-PC 6.1 build 7601 (Windows 7 Home Premium Edition Paket Layanan 1) i586
  • Tanggal Bangun : 23 Agustus 2011 11:47:20
  • Kompiler : MSVC9 (Visual C ++ 2008)
  • Arsitektur : x86
  • Konfigurasikan Perintah : 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"

Jika itu relevan atau mengungkapkan informasi yang berguna, berikut adalah cuplikan layar phpinfo()(bagian mbstring) saya:

tangkapan layar phpinfo

Bagaimana saya bisa mengetahui apakah instalasi PHP saya "dikompilasi dengan versi UNICODE dari Win32 API"? (dan apakah itu benar-benar masuk akal?)

Wesley Murch
sumber
5
Terpilih karena Wesleys harus waspada terhadap satu sama lain.
Wesley
Sudahkah Anda melakukan sesuatu dalam skrip terkait dengan penyandian? Saya memiliki kebalikan dari masalah ini dengan instalasi win7-64 saya! Php akan membaca umlats & semua itu & program warisan omong kosong saya sedang berkomunikasi dengan istirahat ketika mendapat itu.
Chris K
Maaf untuk menjawab pertanyaan ini, saya hanya tidak mendapatkan jawaban kerja cepat dan kotor yang saya harapkan, dan akhirnya berhenti mengembangkan proyek ini pada Windows. Saya akan segera menginstal PHP 5.4 secara lokal (di windows) sehingga pertanyaannya mungkin tidak lagi berharga bagi saya, jika ada yang ingin menyarankan jawaban yang diterima, saya mendengar semuanya. Sementara itu, upvotes dan terima kasih di sekitar.
Wesley Murch

Jawaban:

3

Saya pikir Anda harus mengunduh binari resmi dari repositori PHP Windows dan menginstalnya (perhatikan jalur instalasi).

Setelah itu, Anda harus mengonfigurasi apache untuk menggunakan biner baru, bukan yang dijalankan secara default. Sederhana:

  • Temukan httpd.conffile Anda di folder WAMP (sesuatu seperti C: \ wamp \ bin \ apache \ ApacheXXX \ conf \ httpd.conf) - mungkin juga melalui trayicon.

  • Oke, sekarang Anda menemukannya menemukan pencocokan string LoadModule php5_module

  • Bagus, ganti saja baris ini dengan baris baru Anda php5_moduleyang mungkin ada di c: /php/php5apache2_2.dll (Anda menyimpan jalur instalasi!). Menghasilkan sesuatu sepertiLoadModule php5_module "c:/php/php5apache2_2.dll"

Voila. Setel ulang wamp server dan uji aplikasi Anda dengan versi php build terbaru untuk windows.

Saya tidak yakin ini akan menyelesaikan masalah Anda, tetapi pasti cara yang nyata untuk dilakukan. Jika Anda memiliki masalah pada pengaturan php, baca artikel ini .

Semoga berhasil!

Thiago Macedo
sumber
2

Tampaknya seolah-olah pertanyaan ini telah di luar sana untuk sementara waktu dan apakah php dikompilasi dengan flag unicode atau tidak tidak mempengaruhi itu dukungan unicode, tetapi jika Anda perlu menentukan apakah gambar PE yang diberikan kemungkinan dikompilasi dengan versi Unicode dari Windows API, dapat Anda gunakan dumpbinuntuk memeriksa impor kernel32.dll yang digunakan. Ini bukan sesuatu yang saya akan lakukan secara pragmatis, tetapi dalam keadaan darurat, dapat bekerja untuk diagnosa.

Sebagai contoh, sebuah executable Unicode bisa daftar:

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

mencatat jumlah fungsi yang diakhiri dengan W, alias Lebar untuk karakter unicode.

Untuk ANSI yang dapat dieksekusi atau DLL, Anda mungkin melihat sesuatu yang lebih dekat ke:

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

dengan sebagian besar fungsi yang berakhiran A, kita dapat melihat executable kemungkinan besar dikompilasi dengan flag ANSI.

Mitch
sumber
2

Berikut adalah beberapa kode yang saya kerjakan untuk menangani mbstringmasalah yang sedang saya hadapi. Saya akhirnya mengulangi setiap kombinasi pengkodean dan opsi sampai salah satu dari mereka menyajikan output yang saya butuhkan. Saya merasa prosedur semacam ini dapat membantu Anda menemukan jawaban yang Anda cari.

Jangan mengandalkan dokumentasi , seperti dalam kasus saya, hasilnya bukan apa yang saya pikir akan dilakukan opsi dan penyandian. Saya ingat dalam pengujian saya, saya akan mendapatkan persegi panjang,? S, dan hal-hal seperti A ~. Pengujian saya persis seperti milik Anda, print_rinfo. Dalam kasus saya, skrip saya mengimpor informasi pelanggan dan penjualan ke Quickbooks, yang tidak dapat menangani UTF-8. (Entah QB itu sendiri tidak bisa atau Driver QODBC tidak bisa) Tildes, kuburan, dan umlats keluar dari pertanyaan.

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);   

Tautan di atas adalah http://www.php.net/manual/en/function.mb-detect-encoding.php#89915 dan jika Google menemukan Anda di sini, pasti baca itu.

Chris K
sumber
1

Saya yakin Anda akan ingin memeriksa untuk melihat apakah PHP dikompilasi dengan mbstring (atau modul mbstring diinstal dan diaktifkan jika Anda menggunakan modul). Jika ekstensi itu diaktifkan harus menyelesaikan masalah Anda. Halaman ini harus memberi tahu Anda segala yang perlu Anda ketahui untuk membuatnya berfungsi.

Harun
sumber
Terima kasih atas sarannya, tapi saya percaya mbstring diinstal dengan benar. Saya menambahkan sedikit info tentang ini ke akhir posting saya. Saya lebih tertarik mempelajari komentar yang saya kutip dari artikel "Versi PHP ANDA yang tidak dikompilasi dengan benar, dan yang menggunakan versi lama ANSI dari Win32 API" , bagaimana cara mengetahui apakah ini yang terjadi, dan apakah ini relevan atau tidak.
Wesley Murch
Saya tidak berpikir dukungan unicode di PHP banyak hubungannya dengan dukungan unicode di API yang digunakan PHP untuk melakukan bisnisnya. Saya menduga yang terakhir adalah masalah daripada yang pertama. (Maaf karena saya tidak punya jawaban untuk masalah ini; saya jijik dengan betapa buruknya PHP setelah mencoba bahasa yang waras jadi saya tidak punya banyak pengalaman dengan itu).
gparent