ฉันจะตรวจสอบได้อย่างไรว่า PHP ถูกคอมไพล์ด้วย Win32 API เวอร์ชัน UNICODE หรือไม่


10

สิ่งนี้เกี่ยวข้องกับการโพสต์ Stack Overflow:

glob () ไม่สามารถค้นหาชื่อไฟล์ที่มีอักขระหลายไบต์บน Windows ได้หรือไม่

ฉันมีปัญหากับ PHP และไฟล์ที่มีอักขระหลายไบต์บน Windows นี่คือกรณีทดสอบของฉัน:

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

แก้ไขเอาต์พุตบนเซิร์ฟเวอร์ UNIX รีโมต:

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
)

เอาต์พุตไม่ถูกต้องแบบโลคัลบน 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
)

นี่คือข้อความที่ตัดตอนมาจากคำตอบที่ฉันเลือกที่จะยอมรับ (ซึ่งจริงๆแล้วเป็นคำพูดจากบทความที่โพสต์ออนไลน์เมื่อ 2 ปีก่อน):

จากความคิดเห็นในบทความนี้: http://www.rooftopsolutions.nl/blog/filesystem-encoding-and-php

ผลลัพธ์จากการติดตั้ง PHP บน Windows อธิบายได้ง่าย: คุณติดตั้ง PHP เวอร์ชันที่ไม่ถูกต้องและใช้เวอร์ชันที่ไม่ได้คอมไพล์เพื่อใช้ Win32 API เวอร์ชัน Unicode ด้วยเหตุผลนี้การเรียกระบบไฟล์ที่ใช้โดย PHP จะใช้ API "ANSI" แบบดั้งเดิมดังนั้นไลบรารี C / C ++ ที่เชื่อมโยงกับ PHP เวอร์ชันนี้จะพยายามแปลงสตริง UTF-8-encoded yout ของคุณเป็น "ANSI" เพจรหัสที่เลือกในสภาพแวดล้อมการทำงาน (ดูคำสั่ง CHCP ก่อนเริ่ม PHP จากหน้าต่างบรรทัดคำสั่ง)

Windows รุ่นของคุณส่วนใหญ่จะไม่รับผิดชอบสิ่งแปลก ๆ นี้ อันที่จริงนี่เป็น PHP เวอร์ชันของคุณซึ่งไม่ได้รวบรวมอย่างถูกต้องและใช้ Win32 API เวอร์ชัน ANSI ดั้งเดิม (สำหรับความเข้ากันได้กับ Windows 95/98 รุ่น 16 บิตที่เก่าซึ่งสนับสนุนระบบไฟล์ในเคอร์เนลจริง ๆ แล้วไม่มีโดยตรง สนับสนุน Unicode แต่ใช้เลเยอร์การแปลงภายในเพื่อแปลง Unicode ไปเป็นเพจรหัส ANSI ในเครื่องก่อนที่จะใช้เวอร์ชัน ANSI จริงของ API)

คอมไพล์ PHP ใหม่โดยใช้ตัวเลือกคอมไพเลอร์เพื่อใช้ Win32 API เวอร์ชัน UNICODE (ซึ่งควรเป็นค่าเริ่มต้นในวันนี้และต่อไปจะเป็นค่าเริ่มต้นสำหรับ PHP ที่ติดตั้งบนเซิร์ฟเวอร์ที่จะไม่เป็น Windows 95 หรือ Windows 98 ... )

ฉันไม่สามารถยืนยันได้ว่านี่เป็นปัญหาของฉันหรือไม่ ฉันใช้phpinfo()และไม่พบสิ่งที่น่าสนใจ แต่ฉันไม่แน่ใจว่าจะมองหาอะไร ฉันใช้XAMPPเพื่อการติดตั้งง่ายดังนั้นฉันจึงไม่แน่ใจว่าจะติดตั้งอย่างไร

ฉันใช้ Windows 7, 64 บิต - ยกโทษให้ความไม่รู้ของฉัน แต่ฉันไม่แน่ใจว่า "Win32" เกี่ยวข้องกับที่นี่หรือไม่ ฉันจะตรวจสอบได้อย่างไรว่า PHP เวอร์ชั่นปัจจุบันของฉันถูกคอมไพล์ด้วยการกำหนดค่าที่กล่าวถึงข้างต้น?

  • เวอร์ชั่น PHP : 5.3.8
  • ระบบ : Windows NT WES-PC 6.1 สร้าง 7601 (Windows 7 Home Premium Edition Service Pack 1) i586
  • วันที่สร้าง : 23 ส.ค. 2011 11:47:20
  • คอมไพเลอร์ : MSVC9 (Visual C ++ 2008)
  • สถาปัตยกรรม : x86
  • กำหนดค่าคำสั่ง : 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"

ในกรณีที่เกี่ยวข้องหรือเปิดเผยข้อมูลที่เป็นประโยชน์นี่คือภาพหน้าจอของฉันphpinfo()(ส่วน mbstring):

ภาพหน้าจอ phpinfo

ฉันจะทราบได้อย่างไรว่าการติดตั้ง PHP ของฉัน "ได้รับการคอมไพล์ด้วย Win32 API เวอร์ชัน UNICODE" หรือไม่ (และนั่นทำให้รู้สึกจริง ๆ ?)


5
โหวตขึ้นเนื่องจาก Wesleys ต้องระวังตัวกัน
Wesley

คุณทำสิ่งใดในสคริปต์เกี่ยวกับการเข้ารหัสหรือไม่ ฉันมีปัญหาตรงข้ามกับการติดตั้ง win7-64 ของฉัน! PHP จะอ่าน umlats & ทั้งหมดที่ & โปรแกรมอึแบบดั้งเดิมที่ฉันกำลังสื่อสารกับการพักเมื่อมันได้รับ
Chris K

ขออภัยที่ประกันตัวคำถามนี้ฉันไม่ได้รับคำตอบที่รวดเร็วและสกปรกฉันหวังและท้ายที่สุดก็หยุดพัฒนาโครงการนี้บน Windows ฉันจะติดตั้ง PHP 5.4 เร็ว ๆ นี้ในพื้นที่ (บน windows) ดังนั้นคำถามอาจไม่มีประโยชน์กับฉันอีกต่อไปหากใครต้องการแนะนำคำตอบที่ได้รับการยอมรับ ในขณะเดียวกัน upvotes และขอบคุณทุกรอบ
Wesley Murch

คำตอบ:


3

ฉันคิดว่าคุณควรดาวน์โหลดไบนารีอย่างเป็นทางการจากที่เก็บ PHP Windowsและติดตั้ง (จดเส้นทางการติดตั้ง)

หลังจากนั้นคุณจะต้องกำหนดค่า apache ให้ใช้ไบนารีใหม่แทนที่จะเป็นไบนารีที่ดำเนินการโดยค่าเริ่มต้น มันง่าย:

  • ค้นหาhttpd.confไฟล์ของคุณในโฟลเดอร์ WAMP (บางอย่างเช่น C: \ wamp \ bin \ apache \ ApacheXXX \ conf \ httpd.conf) - อาจเป็นไปได้ที่จะตรวจดู Trayicon

  • ตกลงตอนนี้คุณพบแล้วพบการจับคู่สตริง LoadModule php5_module

  • ดีเพียงแทนที่บรรทัดนี้ด้วยอันใหม่ของคุณphp5_moduleซึ่งเป็น probaly ใน c: /php/php5apache2_2.dll (คุณบันทึกเส้นทางการติดตั้ง!) ส่งผลให้บางอย่างเช่นLoadModule php5_module "c:/php/php5apache2_2.dll"

voila รีเซ็ตเซิร์ฟเวอร์ wamp และทดสอบแอปพลิเคชันของคุณด้วย php build รุ่นล่าสุดสำหรับ Windows โดยเฉพาะ

ฉันไม่แน่ใจว่าสิ่งนี้จะแก้ปัญหาของคุณได้ แต่แน่นอนว่าเป็นวิธีการที่แท้จริง หากคุณมีปัญหาในการติดตั้ง PHP, อ่านบทความ

โชคดี!


2

ดูเหมือนกับว่าคำถามนี้ได้ถูกปล่อยออกมาชั่วระยะเวลาหนึ่งหรือไม่และ php นั้นถูกคอมไพล์ด้วยแฟล็กยูนิโค้ดหรือไม่นั้นไม่ส่งผลกระทบต่อการสนับสนุนยูนิโค้ด แต่ถ้าคุณต้องการพิจารณาว่าภาพ PE ที่ให้นั้นน่าจะคอมไพล์ Windows API คุณสามารถใช้dumpbinเพื่อตรวจสอบการนำเข้า kernel32.dll ที่ใช้ นี่ไม่ใช่สิ่งที่ฉันจะต้องใช้ในทางปฏิบัติ แต่ในเวลาสั้น ๆ สามารถวินิจฉัยได้

ตัวอย่างเช่นปฏิบัติการ Unicode สามารถแสดงรายการ:

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

สังเกตจำนวนของฟังก์ชันที่ลงท้ายด้วย W หรือที่เรียกว่า Wide สำหรับอักขระ Unicode

สำหรับปฏิบัติการแบบ ANSI หรือ DLL คุณอาจเห็นบางสิ่งที่ใกล้เคียงกับ:

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

ด้วยฟังก์ชั่นส่วนใหญ่ที่ลงท้ายด้วย A เราจะเห็นว่าไฟล์ประมวลผลนั้นน่าจะถูกคอมไพล์ด้วยแฟล็ก ANSI


2

นี่คือรหัสที่ฉันทำงานเพื่อจัดการmbstringปัญหาที่ฉันพบ ฉันสิ้นสุดการวนซ้ำผ่านการเข้ารหัสและตัวเลือกทุกชุดจนกระทั่งหนึ่งในนั้นแสดงผลลัพธ์ที่ฉันต้องการ ฉันรู้สึกว่าขั้นตอนแบบนี้อาจช่วยคุณค้นหาคำตอบที่คุณต้องการ

อย่าพึ่งพาเอกสารเช่นเดียวกับในกรณีของฉันผลลัพธ์ไม่ใช่สิ่งที่ฉันคิดว่าตัวเลือกและการเข้ารหัสจะทำ ฉันจำได้ในการทดสอบของฉันฉันจะได้รับรูปสี่เหลี่ยมผืนผ้าและสิ่งต่าง ๆ เช่น A ~ การทดสอบของฉันเป็นเหมือนของคุณprint_rข้อมูล ในกรณีของฉันสคริปต์ของฉันกำลังนำเข้าข้อมูลลูกค้าและการขายไปยัง Quickbooks ซึ่งไม่สามารถจัดการ UTF-8 ได้ (QB นั้นไม่สามารถทำได้หรือโปรแกรมควบคุม QODBC ไม่สามารถทำได้) Tildes, graves และ umlats ไม่เป็นที่ต้องการ

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

ลิงก์ข้างต้นคือhttp://www.php.net/manual/en/function.mb-detect-encoding.php#89915และหาก Google พบคุณที่นี่ให้ไปอ่าน


1

ฉันเชื่อว่าคุณจะต้องตรวจสอบเพื่อดูว่า PHP ถูกคอมไพล์ด้วยmbstring (หรือติดตั้งโมดูล mbstring และเปิดใช้งานหากคุณใช้โมดูล) การเปิดใช้งานส่วนขยายนั้นควรแก้ปัญหาของคุณ หน้านี้ควรบอกทุกสิ่งที่คุณจำเป็นต้องรู้เพื่อให้มันใช้งานได้


ขอบคุณสำหรับคำแนะนำ แต่ฉันเชื่อว่า mbstring ถูกติดตั้งอย่างถูกต้อง ฉันเพิ่มข้อมูลเล็กน้อยเกี่ยวกับเรื่องนี้ในตอนท้ายของโพสต์ ฉันสนใจที่จะเรียนรู้เกี่ยวกับความคิดเห็นที่ฉันอ้างถึงจากบทความ"PHP เวอร์ชันของคุณซึ่งไม่ได้รวบรวมอย่างถูกต้องและใช้ Win32 API รุ่น ANSI ดั้งเดิม"วิธีการตรวจสอบว่าเป็นกรณีนี้หรือไม่และ ไม่ว่าจะเกี่ยวข้องหรือไม่
Wesley Murch

ฉันไม่คิดว่าการสนับสนุน Unicode ใน PHP นั้นเกี่ยวข้องกับการสนับสนุน Unicode ใน API ที่ PHP ใช้ในการทำธุรกิจ ฉันสงสัยว่าหลังเป็นปัญหามากกว่าอดีต (ขออภัยที่ฉันไม่มีคำตอบสำหรับปัญหาแม้ว่า; ฉันเบื่อหน่ายกับความน่ากลัวของ PHP อย่างสมบูรณ์หลังจากลองใช้ภาษาที่มีสติดังนั้นฉันจึงไม่ได้มีประสบการณ์กับมันมากนัก)
gparent
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.