พิมพ์ตัวแปรการหล่อใน PHP, อะไรคือเหตุผลเชิงปฏิบัติสำหรับการทำเช่นนี้?


45

PHP เป็นส่วนใหญ่ของเราทราบว่ามีการพิมพ์ที่อ่อนแอ สำหรับคนที่ไม่ทำ PHP.net พูดว่า:

PHP ไม่ต้องการคำนิยามประเภทที่ชัดเจน (หรือสนับสนุน) ในการประกาศตัวแปร ชนิดของตัวแปรถูกกำหนดโดยบริบทที่ใช้ตัวแปรนั้น

ไม่ว่าจะชอบหรือเกลียด PHP ก็สร้างตัวแปรใหม่ขึ้นมาทันที ดังนั้นรหัสต่อไปนี้ถูกต้อง:

$var = "10";
$value = 10 + $var;
var_dump($value); // int(20)

PHP ยังอนุญาตให้คุณสร้างตัวแปรอย่างชัดเจนเช่น:

$var = "10";
$value = 10 + $var;
$value = (string)$value;
var_dump($value); // string(2) "20"

ทั้งหมดนี้ยอดเยี่ยม ... แต่สำหรับชีวิตของฉันฉันไม่สามารถเข้าใจถึงเหตุผลที่ปฏิบัติได้สำหรับการทำเช่นนี้

ฉันไม่มีปัญหากับการพิมพ์ที่แข็งแกร่งในภาษาที่รองรับเช่น Java ไม่เป็นไรและฉันเข้าใจอย่างถ่องแท้ นอกจากนี้ฉันรู้และเข้าใจถึงประโยชน์ของการบอกกล่าวชนิดในพารามิเตอร์ฟังก์ชัน

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

$var = "10";
$value = (int)$var;
$value = $value . ' TaDa!';
var_dump($value); // string(8) "10 TaDa!"

ดังนั้นประเด็นคืออะไร


ลองดูตัวอย่างเชิงทฤษฎีเกี่ยวกับโลกที่ผู้ใช้กำหนดรูปแบบการพิมพ์ใน PHP :

  1. คุณบังคับให้โยนตัวแปร$fooเป็น→int(int)$foo
  2. $fooคุณพยายามที่จะเก็บค่าสตริงในตัวแปร
  3. PHP พ่นข้อยกเว้น !! ←นั่นจะทำให้รู้สึก ทันใดนั้นมีเหตุผลสำหรับการคัดเลือกประเภทที่ผู้ใช้กำหนดอยู่!

ความจริงที่ว่า PHP จะสลับสิ่งต่าง ๆ ตามความจำเป็นทำให้ผู้ใช้กำหนดประเภทการหล่อไม่ชัดเจน ตัวอย่างเช่นโค้ดสองตัวอย่างต่อไปนี้เทียบเท่า:

// example 1
$foo = 0;
$foo = (string)$foo;
$foo = '# of Reasons for the programmer to type cast $foo as a string: ' . $foo;

// example 2
$foo = 0;
$foo = (int)$foo;
$foo = '# of Reasons for the programmer to type cast $foo as a string: ' . $foo;

หนึ่งปีหลังจากที่เริ่มถามคำถามนี้เดาว่าใครที่พบว่าตัวเองใช้ typecasting ในสภาพแวดล้อมจริง ขอแสดงความนับถือ

ข้อกำหนดคือการแสดงค่าเงินในเว็บไซต์สำหรับเมนูร้านอาหาร การออกแบบไซต์ต้องการให้ตัดศูนย์ต่อท้ายเพื่อให้การแสดงผลมีลักษณะดังนี้:

Menu Item 1 .............. $ 4
Menu Item 2 .............. $ 7.5
Menu Item 3 .............. $ 3

วิธีที่ดีที่สุดที่ฉันพบว่าทำอย่างนั้นเพื่อเลือกตัวแปรเป็นทุ่น:

$price = '7.50'; // a string from the database layer.
echo 'Menu Item 2 .............. $ ' . (float)$price;

PHP จดจ้องกับเลขศูนย์ต่อท้ายของ float จากนั้น recasts ลอยเป็นสตริงสำหรับการต่อข้อมูล


สิ่งนี้ -> $ value = $ value 'TaDa!'; จะแปลงค่า $ กลับเป็นสตริงก่อนทำการกำหนดให้เป็นมูลค่าสุดท้ายของมูลค่า $ ไม่แปลกใจจริงๆที่ถ้าคุณบังคับนักแสดงประเภทคุณจะได้นักแสดงประเภท ไม่แน่ใจว่ามีประเด็นอะไรในการถามว่าประเด็นคืออะไร?
Chris

"# 3. PHP มีข้อยกเว้น !! <--- มันสมเหตุสมผลแล้ว" จริงๆแล้วมันจะไม่สมเหตุสมผลเลย นั่นไม่ใช่แม้แต่ปัญหาใน Java, JavaScript หรือภาษา C-syntax อื่น ๆ ที่ฉันรู้ ใครในใจที่ถูกต้องจะเห็นว่าเป็นพฤติกรรมที่พึงปรารถนา คุณต้องการที่จะ(string)ปลดเปลื้องทุกที่ ?
Nicole

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

หากคุณกำลังพูดว่า$intval.'bar'มีข้อยกเว้นฉันยังคงไม่เห็นด้วย ไม่ได้มีข้อยกเว้นในภาษาใด ๆ (ทุกภาษาที่ฉันรู้จักทำการแสดงอัตโนมัติหรือ.toString()) หากคุณกำลังพูดว่า$intval = $stringvalเกิดข้อผิดพลาดคุณกำลังพูดถึงภาษาที่พิมพ์ออกมาอย่างรุนแรง ฉันไม่ได้ตั้งใจจะหยาบคายดังนั้นขอโทษด้วยถ้าฉันทำ ฉันคิดว่ามันขัดกับสิ่งที่นักพัฒนาซอฟต์แวร์ทุกคนคุ้นเคยและสะดวกสบายน้อยกว่ามาก
Nicole

@Stephen - ฉันโพสต์คำตอบหลังจากการตรวจสอบบางอย่าง ผลลัพธ์ที่น่าสนใจจริง ๆ - ฉันคิดว่า 2 กรณีจะแสดงวัตถุประสงค์ในการคัดเลือกนักแสดง แต่ PHP นั้นแปลกกว่าที่ฉันคิด
Nicole

คำตอบ:


32

ในภาษาที่มีการพิมพ์น้อยการหล่อแบบมีอยู่เพื่อลบความคลุมเครือในการดำเนินการที่พิมพ์เมื่อมิฉะนั้นคอมไพเลอร์ / ล่ามจะใช้คำสั่งหรือกฎอื่น ๆ เพื่อให้สันนิษฐานว่าการดำเนินการที่จะใช้

โดยปกติแล้วฉันจะบอกว่า PHP เป็นไปตามรูปแบบนี้ แต่ในกรณีที่ฉันตรวจสอบแล้ว PHP ก็มีวิธีการตอบโต้ในแต่ละครั้ง

นี่คือกรณีเหล่านี้โดยใช้ JavaScript เป็นภาษาเปรียบเทียบ

การรวมสตริง

เห็นได้ชัดว่านี่ไม่ใช่ปัญหาใน PHP เพราะมีตัวดำเนินการต่อสตริงที่แยกกัน ( .) และการเพิ่ม ( +)

JavaScript
var a = 5;
var b = "10"
var incorrect = a + b; // "510"
var correct = a + Number(b); // 15

การเปรียบเทียบสตริง

บ่อยครั้งในระบบคอมพิวเตอร์ "5" มากกว่า "10" เพราะมันไม่ได้แปลความหมายเป็นตัวเลข ไม่เช่นนั้นใน PHP ซึ่งแม้ว่าทั้งสองจะเป็นสตริง แต่ก็ตระหนักได้ว่ามันเป็นตัวเลขและไม่จำเป็นต้องใช้ cast)

JavaScript
console.log("5" > "10" ? "true" : "false"); // true
PHP
echo "5" > "10" ? "true" : "false";  // false!

ฟังก์ชั่นการพิมพ์ลายเซ็นต์

PHP ใช้การตรวจสอบชนิดกระดูกเปลือยบนฟังก์ชันของลายเซ็น แต่น่าเสียดายที่มันมีข้อบกพร่อง

ฉันคิดว่าฉันอาจจะทำสิ่งผิดปกติ แต่ความคิดเห็นในเอกสารยืนยันว่ามีชนิดในตัวนอกเหนือจากอาร์เรย์ไม่สามารถใช้ในลายเซ็นฟังก์ชัน PHP ได้ - แม้ว่าข้อความแสดงข้อผิดพลาดจะทำให้เข้าใจผิด

PHP
function testprint(string $a) {
    echo $a;
}

$test = 5;
testprint((string)5); // "Catchable fatal error: Argument 1 passed to testprint()
                      //  must be an instance of string, string given" WTF?

และไม่เหมือนกับภาษาอื่น ๆ ที่ฉันรู้จักแม้ว่าคุณจะใช้ภาษาที่เข้าใจแล้วก็ตาม null จะไม่สามารถผ่านไปยังอาร์กิวเมนต์นั้นได้อีกต่อไป ( must be an instance of array, null given) โง่แค่ไหน

การตีความแบบบูล

[ แก้ไข ]: อันนี้ใหม่ ฉันคิดว่าอีกกรณีหนึ่งและตรรกะกลับเป็นจาก JavaScript อีกครั้ง

JavaScript
console.log("0" ? "true" : "false"); // True, as expected. Non-empty string.
PHP
echo "0" ? "true" : "false"; // False! This one probably causes a lot of bugs.

โดยสรุปแล้วสิ่งเดียวที่มีประโยชน์ที่ฉันคิดได้คือ ... (drumroll)

ตัดทอนประเภท

กล่าวอีกนัยหนึ่งเมื่อคุณมีค่าประเภทหนึ่ง (พูดสตริง) และคุณต้องการตีความมันเป็นประเภทอื่น (int) และคุณต้องการบังคับให้เป็นหนึ่งในชุดของค่าที่ถูกต้องในประเภทนั้น:

$val = "test";
$val2 = "10";
$intval = (int)$val; // 0
$intval2 = (int)$val2; // 10
$boolval = (bool)$intval // false
$boolval2 = (bool)$intval2 // true
$props = (array)$myobject // associative array of $myobject's properties

ฉันไม่สามารถเห็นสิ่งที่ upcasting (ประเภทที่ครอบคลุมค่ามากขึ้น) จะได้รับคุณจริง ๆ

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


ตกลงE_NOTICEแล้วเป็นไงล่ะ? :)
สตีเฟ่น

@ สตีเฟ่นE_NOTICEอาจจะโอเค แต่สำหรับฉันแล้วรัฐที่คลุมเครือเกี่ยวกับ - คุณจะรู้ได้อย่างไรโดยการดูโค้ดหนึ่งบิตถ้าตัวแปรอยู่ในสถานะนั้น (ถูกแปลงไปที่อื่น) นอกจากนี้ฉันพบเงื่อนไขอื่นและเพิ่มลงในคำตอบของฉัน
นิโคล

1
สำหรับการประเมินผลแบบบูลเอกสาร PHP ระบุอย่างชัดเจนว่าอะไรเป็นเท็จเมื่อประเมินเป็นบูลีนและทั้งสตริงว่างและสตริง "0" ถือว่าเป็นเท็จ ดังนั้นแม้ว่าจะรู้สึกแปลกประหลาด แต่ก็เป็นพฤติกรรมปกติและคาดหวัง
Jacek Prucia

เพื่อเพิ่มบิตให้กับความสับสน: echo "010" == 010 และecho "0x10" == 0x10;-)
vartec

1
โปรดทราบว่าตั้งแต่PHP 7คำตอบของคำแนะนำนี้เกี่ยวกับการใบ้ประเภทเซนต์คิตส์และเนวิสนั้นไม่ถูกต้อง
John V.

15

คุณกำลังผสมแนวคิดประเภทที่อ่อนแอ / แข็งแกร่งและไดนามิก / คงที่

PHP มีจุดอ่อนและไดนามิก แต่ปัญหาของคุณอยู่ที่แนวคิดแบบไดนามิก นั่นหมายความว่าตัวแปรไม่มีประเภทค่าทำ

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

สถานการณ์หนึ่งที่ฉันพิมพ์ค่า cast เป็นประจำคือพารามิเตอร์ SQL ตัวเลข คุณควรจะ sanitize / escape ค่าอินพุตใด ๆ ที่คุณแทรกลงในคำสั่ง SQL หรือ (ดีกว่ามาก) ใช้เคียวรีแบบกำหนดพารามิเตอร์ แต่ถ้าคุณต้องการค่าบางอย่างที่ต้องเป็นจำนวนเต็มมันจะง่ายกว่าที่จะใช้มัน

พิจารณา:

function get_by_id ($id) {
   $id = (int)$id;
   $q = "SELECT * FROM table WHERE id=$id LIMIT 1";
   ........
}

ถ้าฉันปล่อยให้บรรทัดแรก$idจะเป็นเวกเตอร์ง่าย ๆ สำหรับการฉีด SQL นักแสดงทำให้แน่ใจว่ามันเป็นจำนวนเต็มไม่เป็นอันตราย ความพยายามใด ๆ ที่จะแทรก SQL บางอันก็จะส่งผลให้แบบสอบถามid=0


ฉันจะยอมรับสิ่งนั้น ตอนนี้เท่าที่ประโยชน์ของการหล่อประเภท?
Stephen

เป็นเรื่องตลกที่คุณนำ SQL injection มาใช้ ฉันโต้เถียงกันเกี่ยวกับเรื่องนี้กับคนที่ใช้เทคนิคนี้เพื่อฆ่าเชื้อการป้อนข้อมูลของผู้ใช้ แต่วิธีนี้แก้ปัญหาที่ mysql_real_escape_string($id);ยังไม่ได้?
สตีเฟ่น

แน่นอนว่ามันสั้นกว่า :-) สำหรับสตริงที่ฉันใช้การค้นหาแบบกำหนดพารามิเตอร์หรือ (ถ้าใช้นามสกุล mysql แบบเก่า) ให้หลีกเลี่ยง
Javier

2
mysql_real_escape_string()มีช่องโหว่ในการไม่ทำอะไรกับสตริงเช่น '0x01ABCDEF' (เช่นการแทนเลขฐานสิบหกของจำนวนเต็ม) ในการเข้ารหัสแบบหลายไบต์ (ไม่ใช่ Unicode lucklily) สตริงเช่นนี้สามารถใช้ในการทำลายแบบสอบถาม (เพราะได้รับการประเมินโดย MySQL เป็นสิ่งที่มีคำพูด) นั่นเป็นเหตุผลที่ค่าmysql_real_escape_string()มิได้is_int()เป็นตัวเลือกที่ดีที่สุดสำหรับการรับมือกับค่าจำนวนเต็ม กำลังแสดงภาพคือ
Mchl

ลิงก์ที่มีรายละเอียดเพิ่มเติม: ilia.ws/archives/…
Mchl

4

ใช้ครั้งเดียวสำหรับการแคสติ้งประเภทใน PHP ที่ฉันได้พบ:

ฉันกำลังพัฒนาแอพ android ซึ่งทำให้การร้องขอ HTTP ไปยังสคริปต์ PHP บนเซิร์ฟเวอร์เพื่อดึงข้อมูลจากฐานข้อมูล สคริปต์เก็บข้อมูลในรูปแบบของวัตถุ PHP (หรืออาเรย์แบบเชื่อมโยง) และส่งคืนเป็นวัตถุ JSON ไปยังแอป ฉันจะได้รับสิ่งนี้:

{ "user" : { "id" : "1", "name" : "Bob" } }

แต่ด้วยการใช้ PHP ในการหล่อ(int)รหัสผู้ใช้เมื่อเก็บวัตถุ PHP ฉันได้รับสิ่งนี้กลับไปที่แอพแทน:

{ "user" : { "id" : 1, "name" : "Bob" } }

จากนั้นเมื่อมีการแยกวิเคราะห์วัตถุ JSON ในแอปมันจะช่วยฉันในการแยกวิเคราะห์ ID เป็นจำนวนเต็ม!

เห็นว่ามีประโยชน์มาก


ฉันไม่ได้พิจารณาการจัดรูปแบบข้อมูลสำหรับระบบภายนอกที่ใช้งานได้ดี +1
Stephen

โดยเฉพาะอย่างยิ่งเมื่อพูดถึง JSON กับระบบภายนอกเช่น Elasticsearch json_encode () - ค่า ed "5" จะให้ผลลัพธ์ที่แตกต่างกันมากกว่าค่า 5
Johan Fredrik Varen

3

ตัวอย่างหนึ่งคือวัตถุที่มีวิธีการ __toString A: VS$str = $obj->__toString(); $str = (string) $obj;การพิมพ์ที่สองมีน้อยกว่ามากและสิ่งพิเศษคือเครื่องหมายวรรคตอนซึ่งใช้เวลาในการพิมพ์นานกว่า ฉันยังคิดว่ามันอ่านได้มากขึ้นแม้ว่าคนอื่นอาจไม่เห็นด้วย

อีกประการหนึ่งคือการทำให้อาร์เรย์เดียวองค์ประกอบ: VSarray($item); (array) $item;สิ่งนี้จะใส่ประเภทสเกลาร์ใด ๆ (จำนวนเต็มทรัพยากร ฯลฯ ) ไว้ในอาร์เรย์
ถ้า$itemเป็นวัตถุคุณสมบัติของมันจะกลายเป็นกุญแจไปสู่ค่าของมัน อย่างไรก็ตามฉันคิดว่าการแปลงอาเรย์เป็นออบเจ็กต์แปลกไปหน่อย: คุณสมบัติส่วนตัวและได้รับการป้องกันเป็นส่วนหนึ่งของอาเรย์และเปลี่ยนชื่อ ในการอ้างอิงเอกสาร PHP : ตัวแปรส่วนตัวมีชื่อคลาสต่อท้ายกับชื่อตัวแปร ตัวแปรที่ได้รับการป้องกันจะมีเครื่องหมาย '*' ต่อท้ายกับชื่อตัวแปร

การใช้งานอื่นคือการแปลงข้อมูล GET / POST เป็นประเภทที่เหมาะสมสำหรับฐานข้อมูล MySQL สามารถจัดการได้ด้วยตัวเอง แต่ฉันคิดว่าเซิร์ฟเวอร์ที่รองรับ ANSI มากกว่านั้นอาจปฏิเสธข้อมูล เหตุผลที่ฉันพูดถึงฐานข้อมูลก็คือในกรณีอื่น ๆ ส่วนใหญ่ข้อมูลจะมีการดำเนินการตามประเภทของมันในบางจุด (เช่น int / ลอยมักจะมีการคำนวณดำเนินการกับพวกเขา ฯลฯ )


นี่เป็นตัวอย่างที่ดีของการใช้งานการพิมพ์แบบหล่อ แต่ผมไม่เชื่อว่าพวกเขาเติมเต็มความต้องการ ใช่คุณสามารถแปลงวัตถุเป็นอาร์เรย์ แต่ทำไม? ฉันเดาว่าเพราะคุณสามารถใช้ฟังก์ชั่นอาร์เรย์ PHP จำนวนมากมายกับอาร์เรย์ใหม่ แต่ฉันไม่สามารถเข้าใจได้ว่ามันจะมีประโยชน์อย่างไร นอกจากนี้ PHP มักจะสร้างข้อความค้นหาสตริงเพื่อส่งไปยังฐานข้อมูล MySQL ดังนั้นประเภทตัวแปรจึงไม่เกี่ยวข้อง (การแปลงสตริงโดยอัตโนมัติจากintหรือfloatจะเกิดขึ้นเมื่อสร้างแบบสอบถาม) (array) $itemเป็นที่เรียบร้อยแต่มีประโยชน์หรือไม่
Stephen

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

Aha! คุณอาจพบเหตุผลที่ถูกต้องกับการค้นหาพารามิเตอร์
สตีเฟ่น

0

สคริปต์นี้:

$tags = _GET['tags'];
foreach ($tags as $tag) {
    echo 'tag: ', $tag;
}

จะทำงานได้ดีscript.php?tags[]=oneแต่จะล้มเหลวscript.php?tags=oneเพราะ_GET['tags']ส่งคืนอาร์เรย์ในกรณีแรก แต่ไม่ใช่ในวินาที เนื่องจากสคริปต์ถูกเขียนขึ้นเพื่อคาดหวังอาร์เรย์ (และคุณมีการควบคุมสตริงข้อความค้นหาที่ส่งไปยังสคริปต์น้อยลง) ปัญหาสามารถแก้ไขได้โดยการส่งผลลัพธ์จาก_GET:

$tags = (array) _GET['tags'];
foreach ($tags as $tag) {
    echo 'tag: ', $tag;
}

0

นอกจากนี้ยังสามารถใช้เป็นวิธีที่รวดเร็วและสกปรกเพื่อให้มั่นใจว่าข้อมูลที่ไม่น่าเชื่อถือจะไม่ทำลายบางสิ่งเช่นหากใช้บริการระยะไกลที่มีการตรวจสอบอึและต้องยอมรับตัวเลขเท่านั้น

$amount = (float) $_POST['amount'];

if( $amount > 0 ){
    $remoteService->doacalculationwithanumber( $amount );    
}

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


1
ยกเว้นว่ามันจะไม่แตก แม้ว่าจะ$_POST['amount']มีสตริงขยะ แต่ php ก็จะประเมินว่ามันไม่มากกว่าศูนย์ หากมันมีสตริงที่แสดงถึงจำนวนบวกก็จะประเมินความจริง
Stephen

1
ไม่จริงทั้งหมด พิจารณาว่าจำนวนเงินจะถูกส่งไปยังบริการของบุคคลที่สามภายในเงื่อนไขซึ่งจะต้องได้รับหมายเลข หากใครบางคนต้องผ่านใน $ _POST ['amount'] = "100 bobbins" การลบ (float) จะยังคงอนุญาตให้เงื่อนไขผ่าน แต่จำนวนเงิน $ จะไม่ใช่ตัวเลข
Gruffputs

-2

หนึ่ง "ใช้" ของ PHP re-casting ตัวแปร on-the-fly ที่ฉันเห็นใช้บ่อยคือเมื่อดึงข้อมูลจากแหล่งภายนอก (ผู้ใช้หรือฐานข้อมูลผู้ใช้) มันช่วยให้ coders (โปรดทราบว่าฉันไม่ได้พูดว่านักพัฒนา)ละเว้น (หรือไม่ได้เรียนรู้) ประเภทข้อมูลที่แตกต่างกันที่มีอยู่จากแหล่งที่แตกต่างกัน

หนึ่งรหัส(โปรดทราบว่าฉันไม่ได้พูดว่านักพัฒนา)ซึ่งมีรหัสที่ฉันได้รับและยังคงรักษาดูเหมือนว่าจะไม่ทราบว่ามีความแตกต่างระหว่างสตริง"20"ที่ส่งกลับใน$_GETตัวแปร super เพื่อระหว่างการดำเนินการจำนวนเต็ม20 + 20เมื่อเธอเพิ่ม ค่าในฐานข้อมูล เธอโชคดีที่ PHP ใช้.สำหรับการเรียงสตริงและไม่+เหมือนกับภาษาอื่น ๆ เพราะฉันเห็นโค้ดของเธอ "เพิ่ม" สองสตริง ( varcahrจาก MySQL และค่าจาก$_GET) และรับ int

นี่เป็นตัวอย่างที่ใช้ได้จริงหรือไม่? เฉพาะในแง่ที่ว่ามันจะทำให้โคเดอร์หลบไปโดยไม่ทราบว่าดาต้าประเภทใดที่ทำงานด้วย ฉันเกลียดมันเป็นการส่วนตัว


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

ขอบคุณสตีเฟ่น ฉันอาจใช้คำมากเกินไปที่จะพูดว่า "PHP ช่วยให้ผู้ที่ไม่ทราบว่าประเภทข้อมูลคือการสร้างแอปพลิเคชันที่ทำสิ่งที่พวกเขาคาดหวังภายใต้เงื่อนไขที่เหมาะ"
dotancohen
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.