เหตุใดจึงต้องใช้ฟังก์ชั่น sprintf ใน PHP


188

ฉันพยายามเรียนรู้เพิ่มเติมเกี่ยวกับฟังก์ชั่น PHP sprintf () แต่ php.net ไม่ได้ช่วยฉันมากเท่าที่ฉันยังสับสนอยู่ทำไมคุณต้องการใช้มัน

ลองดูตัวอย่างของฉันด้านล่าง

ทำไมต้องใช้สิ่งนี้:

$output = sprintf("Here is the result: %s for this date %s", $result, $date);

เมื่อทำสิ่งนี้จะเหมือนกันและง่ายกว่าในการเขียน IMO:

$output = 'Here is the result: ' .$result. ' for this date ' .$date;

ฉันทำอะไรบางอย่างหายไปหรือเปล่า


40
+1 คำถามที่ดี ฉันไม่ค่อยได้ใช้มันดังนั้นฉันสนใจที่จะดูคำตอบ
zombat

6
โปรดทราบว่าตัวอย่างที่สองของคุณไม่เท่ากันตัวอย่างแรกจะกำหนดผลลัพธ์ให้$outputในขณะที่ตัวอย่างที่สองเป็นechoตัวอย่าง
Daniel Pryden

ฉันใช้มันเป็นการส่วนตัวเมื่อฉันต่อสิ่งต่าง ๆ เข้าด้วยกัน เป็นเพียงจริงๆแล้วฉันพบว่ามีประโยชน์สำหรับการอ่านส่วนใหญ่
AlexMorley-Finch

คำตอบ:


130

sprintf มีความสามารถในการจัดรูปแบบทั้งหมดของ printf ดั้งเดิมซึ่งหมายความว่าคุณสามารถทำได้มากกว่าเพียงแค่ใส่ค่าตัวแปรในสตริง

ตัวอย่างเช่นระบุรูปแบบตัวเลข (ฐานสิบหกฐานแปด) จำนวนทศนิยมการเสริมและอื่น ๆ Google สำหรับ printf และคุณจะพบตัวอย่างมากมาย บทความวิกิพีเดีย printfควรจะได้รับคุณเริ่มต้น


46
หลายปีที่ผ่านมาฉันเขียนฟังก์ชันที่ดีสำหรับตัวเลขที่ไม่มีการเติมเต็ม ใช้สำหรับทุกวัยก่อนที่ฉันจะรู้ตัวว่าฉันทำได้sprintf('%03d', $num)
DisgruntledGoat

5
PHP sprintf มีความสามารถในการจัดรูปแบบทั้งหมด ... จริง ๆ แล้วไม่มีความสำคัญ%,8dเช่นการรับ 8 หลักที่ถูกต้องและจำนวนเต็มคั่นด้วยเครื่องหมายจุลภาค การใช้งานnumber_formatไม่สะดวกในprintfสไตล์
e2-e4

3
@DisgruntledGoat คุณสามารถแยกสตริงการจัดรูปแบบนั้น ('% 03d') ได้ไหม? ฉันคิดว่ามันจะเป็นประโยชน์จริงๆ ขอบคุณ
นาย Smee

3
คุณยังสามารถทำซ้ำและเรียงลำดับอาร์กิวเมนต์ที่จะแสดงอีกครั้ง เช่นsprintf('%2$s %1$s, my name is also %1$s.', 'World', 'Hello');ส่งผลให้Hello World, my name is also World.
fyrye

77

มีกรณีการใช้งานมากมายสำหรับ sprintf แต่วิธีหนึ่งที่ฉันใช้คือการจัดเก็บสตริงเช่นนี้: 'Hello, My Name is% s' ในฐานข้อมูลหรือค่าคงที่ในคลาส PHP ด้วยวิธีนี้เมื่อฉันต้องการใช้สตริงนั้นฉันก็สามารถทำได้:

$name = 'Josh';
// $stringFromDB = 'Hello, My Name is %s';
$greeting = sprintf($stringFromDB, $name);
// $greetting = 'Hello, My Name is Josh'

เป็นหลักจะช่วยให้การแยกบางอย่างในรหัส ถ้าฉันใช้ 'สวัสดีชื่อของฉันคือ% s' ในหลาย ๆ ที่ในรหัสของฉันฉันสามารถเปลี่ยนเป็น '% s คือชื่อของฉัน' ในที่เดียวและมันจะอัปเดตทุกที่อื่นโดยอัตโนมัติโดยไม่ต้องไปแต่ละอินสแตนซ์ concatenations


8
นี้. ตอนนี้เพิ่มอาร์กิวเมนต์จำนวนและการแปล:]
Konerak

46

การใช้งานอื่นsprintfอยู่ในแอปพลิเคชันที่แปลเป็นภาษาท้องถิ่นเพื่อเป็นข้อโต้แย้งsprintfไม่จำเป็นต้องอยู่ในลำดับที่ปรากฏในสตริงรูปแบบ

ตัวอย่าง:

$color = 'blue';
$item = 'pen';

sprintf('I have a %s %s', $color, $item);

แต่ภาษาอย่างฝรั่งเศสสั่งให้คำต่างออกไป:

$color = 'bleu';
$item = 'stylo';

sprintf('J\'ai un %2$s %1$s', $color, $item);

(ใช่ภาษาฝรั่งเศสของฉันแย่มาก: ฉันเรียนภาษาเยอรมันที่โรงเรียน!)

ในความเป็นจริงคุณจะใช้ gettextเพื่อจัดเก็บสตริงที่แปลแล้ว แต่คุณจะได้แนวคิด



37

แปลง่ายกว่า

echo _('Here is the result: ') . $result . _(' for this date ') . $date;

ตอนนี้สตริงการแปล (gettext) คือ:

  • นี่คือผลลัพธ์:
  • สำหรับวันนี้

เมื่อแปลเป็นภาษาอื่นมันอาจเป็นไปไม่ได้หรือผลลัพธ์นั้นเป็นประโยคที่แปลกมาก

ตอนนี้ถ้าคุณมี

echo sprintf(_("Here is the result: %s for this date %s"), $result, $date);

สตริงการแปล (gettext) คือตอนนี้:

  • นี่คือผลลัพธ์:% s สำหรับวันที่นี้% s

ซึ่งเหมาะสมกว่าและมีความยืดหยุ่นในการแปลเป็นภาษาอื่น ๆ


1
ฉันเห็นว่าสิ่งนี้จะมีประโยชน์มาก +1
JasonDavis

6
แม้ว่าการแปลมันน่าจะดีกว่าถ้าใช้การระบุตำแหน่งเพื่อให้มีความยืดหยุ่นเป็นพิเศษเมื่อแปลเช่น: echo sprintf(_("Here is the result: %1$s for this date %2$s"), $result, $date);นั่นจะช่วยให้การแปลแก้ไขวลีเช่นFor the date %2$s, the result is %1$s
PatrikAkerstrand

1
แม้ว่าพวกเขาจะไม่ได้อยู่ในสายเดิมคุณสามารถใส่ไว้ในการแปลและพวกเขาจะทำงาน
spectras

17

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

ตัวอย่างเช่นเว็บไซต์ของคุณจะพูดว่า "ยินดีต้อนรับกลับ [[ผู้ใช้]]" ที่ด้านบนของหน้า ในฐานะโปรแกรมเมอร์คุณไม่รู้จักหรือสนใจว่า UI นั้นจะเขียนยังไง - คุณเพิ่งรู้ว่าชื่อผู้ใช้จะปรากฏที่ใดที่หนึ่งในข้อความ

ดังนั้นคุณสามารถฝังข้อความลงในโค้ดของคุณโดยไม่ต้องกังวลว่าข้อความนั้นคืออะไร

ไฟล์ Lang (EN_US):

...
$lang['welcome_message'] = 'Welcome back %s';
...

จากนั้นคุณสามารถรองรับข้อความประเภทใด ๆ ในภาษาใด ๆ โดยใช้สิ่งนี้ในรหัส php ที่แท้จริงของคุณ

sprintf($lang['welcome_message'], $user->name())

ฉันไม่เคยมีที่จะต้องกังวลเกี่ยวกับการทำไฟล์ภาษา แต่ไม่ดูเหมือนหนึ่งของการใช้ประโยชน์มากที่สุดกับผม
JasonDavis

ตัวอย่างนี้ทำให้ฉันรู้สึกสมบูรณ์แบบเนื่องจากฉันไม่ได้ใช้แอพพลิเคชั่นแบบหลายภาษามากนัก
MKN Web Solutions

9

ทำไมคุณต้องการใช้

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

en.txt

not_found    = "%s could not be found."
bad_argument = "Bad arguments for function %s."
bad_arg_no   = "Bad argument %d for function %s."

hu.txt

not_found    = "A keresett eljárás (%s) nem található."
bad_argument = "Érvénytelen paraméterek a(z) %s eljárás hívásakor."
bad_arg_no   = "Érvénytelen %d. paraméter a(z) %s eljárás hívásakor."

ตัวแปรที่แทรกไว้ไม่จำเป็นต้องเป็นจุดเริ่มต้นหรือจุดสิ้นสุดในหลายภาษาเท่านั้น

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

/**
 * throws exception with message($name = "ExampleMethod"):
 *  - using en.txt: ExampleMethod could not be found.
 *  - using hu.txt: A keresett eljárás (ExampleMethod) nem található.
 */
throw new Exception(sprintf(Language::Get('not_found'), $name));

/**
 * throws exception with message ($param_index = 3, $name = "ExampleMethod"):
 *  - using en.txt: Bad argument 3 for function ExampleMethod.
 *  - using hu.txt: Érvénytelen 3. paraméter a(z) ExampleMethod eljárás hívásakor.
 */
throw new Exception(sprintf(Language::Get('bad_arg_no'), $param_index, $name));

นอกจากนี้ยังมาพร้อมกับความสามารถเต็มรูปแบบของprintfดังนั้นจึงเป็นหนึ่งซับสำหรับการจัดรูปแบบตัวแปรหลายชนิดเช่น:


8

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

ข้อดีอีกอย่างคือมันช่วยให้คุณสามารถแยกเลย์เอาต์ของสตริงออกจากข้อมูลที่ป้อนเข้ามาได้เช่นเดียวกับการป้อนในพารามิเตอร์ ตัวอย่างเช่นในกรณีของแบบสอบถาม MySQL:

// For security, you MUST sanitise ALL user input first, eg:
$username = mysql_real_escape_string($_POST['username']); // etc.
// Now creating the query:
$query = sprintf("INSERT INTO `Users` SET `user`='%s',`password`='%s',`realname`='%s';", $username, $passwd_hash, $realname);

แน่นอนว่าวิธีนี้มีประโยชน์อื่น ๆ เช่นเมื่อพิมพ์เอาต์พุตเป็น HTML เป็นต้น

แก้ไข: เพื่อเหตุผลด้านความปลอดภัยเมื่อใช้เทคนิคดังกล่าวข้างต้นคุณต้องฆ่าเชื้อตัวแปรอินพุตทั้งหมดด้วยmysql_real_escape_string()ก่อนที่จะใช้วิธีนี้เพื่อป้องกันการโจมตีจากการแทรก MySQL ถ้าคุณแยกอินพุต unsanitised, เว็บไซต์และเซิร์ฟเวอร์ของคุณจะได้รับ hacked (ยกเว้นแน่นอนว่าตัวแปรที่สร้างขึ้นอย่างสมบูรณ์โดยรหัสของคุณและรับประกันว่าจะปลอดภัย)


2
รหัสนั้นมีความเสี่ยงต่อการฉีด SQL ใช้ตัวยึดตำแหน่งไม่ใช่การแก้ไขแบบสอบถาม!
duskwuff -inactive-

@duskwuff - ใช้ตามที่เป็นอยู่คุณพูดถูก ขออภัยฉันแก้ไขคำตอบแล้ว
ซามูเอล Jaeschke

7

การใช้sprintf ()นั้นสะอาดและปลอดภัยกว่ามากในการจัดรูปแบบสตริงของคุณ

ตัวอย่างเช่นเมื่อคุณจัดการกับตัวแปรอินพุตมันจะป้องกันความประหลาดใจที่ไม่คาดคิดโดยการระบุรูปแบบที่คาดไว้ล่วงหน้า (ตัวอย่างเช่นคุณคาดหวังว่าสตริง [ %s] หรือหมายเลข [ %d]) สิ่งนี้อาจช่วยได้ด้วยความเสี่ยงที่อาจเกิดขึ้นจากการฉีด SQLแต่จะไม่ป้องกันหากสตริงประกอบด้วยเครื่องหมายคำพูด

นอกจากนี้ยังช่วยในการจัดการกับลอยคุณสามารถระบุความแม่นยำหลัก (เช่น%.2f) ซึ่งช่วยให้คุณประหยัดจากการใช้ฟังก์ชั่นการแปลง

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

โดยสรุปเป็นแนวปฏิบัติที่ดีที่จะใช้เพื่อให้มีโค้ดที่สะอาดและอ่านได้ง่ายขึ้น

ตัวอย่างเช่นดูตัวอย่างจริงด้านล่าง:

$insert .= "('".$tr[0]."','".$tr[0]."','".$tr[0]."','".$tr[0]."'),";

หรือตัวอย่างง่ายๆที่พิมพ์เช่น'1','2','3','4':

print "foo: '" . $a . "','" . $b . "'; bar: '" . $c . "','" . $d . "'" . "\n";

และพิมพ์ด้วยสตริงที่จัดรูปแบบ:

printf("foo: '%d','%d'; bar: '%d','%d'\n", $a, $b, $c, $d);

โดยที่printf()จะเทียบเท่าsprintf()แต่ส่งเอาต์พุตสตริงที่จัดรูปแบบแทนที่จะส่งคืน (ไปยังตัวแปร)

ข้อใดอ่านได้มากกว่า


1
ฉันไม่เห็นด้วย แต่ก็คุ้มค่าที่จะพูดถึงเมื่อฉันถามเรื่องนี้เมื่อ 6-7 ปีที่แล้วและนึกย้อนกลับไปฉันจำไม่ได้ว่าเคยใช้สิ่งนี้มาตั้งแต่ไหนแล้ว! ฉันหวังว่าจะได้พบสถานที่สำหรับวันหนึ่งและเชื่อว่ามันมีสถานที่ แต่ตลกคิดว่าฉันไม่ได้ใช้มันตั้งแต่ถามคำถามนี้เมื่อหลายปีก่อน!
JasonDavis

ฉันสามารถพูดได้ว่ามันค่อนข้างคล้ายกับการตั้งค่าตัวแปรสำหรับ PDO ใน PHP นอกจากนี้หากคุณต้องการให้อาร์กิวเมนต์อ่านง่ายจากนั้นในกรณีที่ฉันต้องการใช้sprintf()แบ่งออกเป็นหลายบรรทัดที่สตริงที่มีตัวยึดอยู่บน 1 บรรทัดและค่าอยู่ในบรรทัดหรือแม้กระทั่งหลายบรรทัดด้านล่างเยื้องอย่างถูกต้องของ หลักสูตร ใช้การสาธิตของคุณในลักษณะที่ฉันอธิบาย ... i.imgur.com/DFi3ur8.png
JasonDavis

งบเตรียมร่วมกับขั้นตอนการจัดเก็บเป็นวิธีที่ดีที่สุดในการป้องกันการฉีด sql ไม่ใช่ sprintf คุณยังสามารถฉีด sql ได้อย่างง่ายดายโดยใช้ sprintf หากสตริงเกิดขึ้นเพื่อมีคำพูดเดียว
HumbleWebDev

4

แม้ว่าฉันจะเป็นสิ่งเดียวกันเว้นแต่ฉันจะใช้มันเมื่อเร็ว ๆ นี้ เมื่อคุณสร้างเอกสารตามการป้อนข้อมูลของผู้ใช้สิ่งนี้จะเป็นประโยชน์

"<p>Some big paragraph ".$a["name"]." again have tot ake care of space and stuff .". $a["age"]. "also would be hard to keep track of punctuations and stuff in a really ".$a["token"]. paragarapoh.";

ซึ่งสามารถเขียนได้ง่ายเช่น

sprintf("Some big paragraph %s. Again have to take care of space and stuff.%s also wouldnt be hard to keep track of punctuations and stuff in a really %s paragraph",$a,$b,$c);

"<p>Some big paragraph {$a['name']} more words {$a['age']}</p>"หรือคุณสามารถทำสิ่งนี้: อย่างไรก็ตามอย่าลืมที่จะฆ่าเชื้ออินพุตของผู้ใช้หรือคุณเปิดรหัสของคุณได้ถึงช่องโหว่ XSS
บุคคลที่สาม

นอกจากนี้คุณยังสามารถใช้ไวยากรณ์ HEREDOC ในความคิดของฉันทั้งสองอ่านง่ายกว่าไวยากรณ์ sprintf
บุคคลที่สาม

4

นี้:

"<p>Some big paragraph ".$a["name"]." again have to take care of space and stuff .". $a["age"]. "also would be hard to keep track of punctuations and stuff in a really ".$a["token"]. paragraph.";

สามารถเขียนได้:

"<p>Some big paragraph {$a['name']} again have to take care of space and stuff .{$a['age']} also would be hard to keep track of punctuations and stuff in a really {$a['token']} paragraph.";

ในความคิดของฉันนี้ชัดเจนอ่าน แต่ฉันสามารถดูการใช้การแปลหรือการจัดรูปแบบ


3

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

มีตัวอย่างมากมายในคู่มือ PHP

นอกจากนี้สิ่งที่มาพร้อมกับตัวอย่างของ "การเขียนง่ายขึ้น" .. ในขณะที่เสียงสะท้อนอาจจะง่ายต่อการเขียน sprintf อ่านง่ายขึ้นโดยเฉพาะถ้าคุณมีตัวแปรจำนวนมาก

อีกเหตุผลที่ใช้ sprintf หรือ printf อาจเป็นเพราะคุณต้องการให้ผู้ใช้กำหนดรูปแบบผลลัพธ์ของค่าบางอย่าง - คุณสามารถอนุญาตให้ผู้ใช้กำหนดรูปแบบผลลัพธ์ที่เข้ากันได้ของ sprintf อย่างปลอดภัย

โอ้และตัวอย่างของคุณผิดจริงสำหรับส่วนหนึ่ง sprintfกลับสตริง แต่echoไม่ได้ - echoทันทีเอาท์พุทและผลตอบแทนอะไรในขณะที่sprintfเพียงผลตอบแทนมัน


3
  1. หากคุณใช้ C / C ++ แล้วคุณจะถูกนำไปใช้กับฟังก์ชั่น sprintf

  2. มีโอกาสที่ดีที่บรรทัดที่สองจะมีประสิทธิภาพน้อยกว่า Echo ได้รับการออกแบบเป็นคำสั่งเอาต์พุตในขณะที่ sprintf ได้รับการออกแบบมาเพื่อทำการทดแทนโทเค็นสตริง ฉันไม่ใช่คน PHP แต่ฉันสงสัยว่ามีวัตถุอื่น ๆ ที่เกี่ยวข้องกับเสียงสะท้อน หากมันทำหน้าที่เหมือน Java มันจะสร้างสตริงใหม่ทุกครั้งที่บางสิ่งถูกเพิ่มเข้าไปในรายการดังนั้นคุณจะได้ 4 สตริงที่สร้างขึ้น


Java รุ่นล่าสุดจะแปลง String concatenation เป็น StringBuilder ที่อยู่เบื้องหลัง
RodeoClown

1
สตริงใน PHP ไม่ใช่วัตถุ ตัวอย่างที่สองใช้โครงสร้างภาษาแทนการเรียกใช้ฟังก์ชันดังนั้นจะเร็วขึ้นอย่างไม่น่าเชื่อ
Tamlyn


3

ฉันมักจะใช้ sprintf เพื่อให้แน่ใจว่า id ที่มาจากการป้อนข้อมูลของผู้ใช้เป็นจำนวนเต็มเช่น:

// is better use prepared statements, but this is practical sometimes
$query = sprintf("SELECT * from articles where id = %d;",$_GET['article_id']);

นอกจากนี้ยังใช้ในการทำแม่แบบพื้นฐาน (สำหรับอีเมล html หรือสิ่งอื่น ๆ ) เพื่อให้คุณสามารถนำแม่แบบนั้นมาใช้ซ้ำได้ในหลายที่

$mail_body = "Hello %s, ...";
$oneMail = sprintf($mail_body, "Victor");
$anotherMail = sprintf($mail_body, "Juan");

มันมีประโยชน์มากเช่นกันในการจัดรูปแบบตัวเลขในรูปแบบต่าง ๆ (ฐานแปด, ควบคุมตำแหน่งทศนิยม, ฯลฯ )


การใช้ intval นั้นง่ายกว่าไหม ($ _ GET ["article_id"])? จริง ๆ แล้วมันใช้เวลาพิมพ์มากขึ้น ... * จดบันทึกวิธีการของคุณ "Dag nabbit.
97410

สำหรับรหัสประเภทนี้ควรใช้ mysql_real_escape_string (): $ query = sprintf ("SELECT * จากบทความที่ id =% d;", ​​mysql_real_escape_string ($ _ GET ['article_id']));
bruno.braga

3
define('TEXT_MESSAGE', 'The variable "%s" is in the middle!');

sprintf(TEXT_MESSAGE, "Var1");
sprintf(TEXT_MESSAGE, "Var2");
sprintf(TEXT_MESSAGE, "Var3");

3

sprintf มีประโยชน์อย่างยิ่งเมื่อทำการจัดรูปแบบสตริงที่ใช้ตัวเลข ตัวอย่างเช่น,

$oranges = -2.34;
echo sprintf("There are %d oranges in the basket", $oranges);

Output: There are -2 oranges in the basket

ส้มมีการจัดรูปแบบเป็นจำนวนเต็ม (-2) แต่จะล้อมรอบเป็นจำนวนบวกหากมีการใช้% u สำหรับค่าที่ไม่ได้ลงนาม เพื่อหลีกเลี่ยงพฤติกรรมนี้ฉันใช้ฟังก์ชันสัมบูรณ์ abs () เพื่อปัดเศษตัวเลขเป็นศูนย์ดังนี้:

$oranges = -5.67;
echo sprintf("There are %d oranges in the basket", abs($oranges));

Output: There are 5 oranges in the basket

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

$oranges = -3.14;
$apples = 1.5;
echo sprintf("There are %d oranges and %d apples", abs($oranges), abs($apples));

Output: There are 3 oranges and 4 apples

ด้านซ้ายของคำสั่ง sprintf แสดงสตริงและประเภทของค่าที่คาดไว้อย่างชัดเจนในขณะที่ด้านขวาแสดงตัวแปรที่ใช้อย่างชัดเจนและวิธีการจัดการ


ฉันกำลังจะ upvote คำตอบของคุณสำหรับประโยคแรกที่ยอดเยี่ยม ( "sprintf มีประโยชน์อย่างยิ่งเมื่อการจัดรูปแบบสตริงที่ใช้ตัวเลข" ) ซึ่งแน่นอนว่าเป็นจุดที่สำคัญที่สุดsprintfใน PHP แต่จากนั้นดูตัวอย่างที่ซับซ้อนที่สร้างผลไม้จาก "หายไป" fruit :) แต่ละรายการแสดงซ้ำ ๆ เท่านั้น%d(และabs()ซึ่งไม่เกี่ยวข้องกับหัวข้อ) แทนที่จะแสดงตัวเลือกการจัดรูปแบบตัวเลขจำนวนมาก (ซึ่งจะเกี่ยวข้อง) ฉันเปลี่ยนใจ แต่ถ้าคุณปรับปรุงคำตอบฉันจะยังมี upvote ของฉันในตู้เย็นสำหรับคุณ :) ขอบคุณค่ะไชโย!
Sz.

3

ดีsprintf มีความสามารถมากที่สุดเท่าที่เรารู้ว่าตัวอย่างดังต่อไปนี้:

ไม่กี่เดือนที่ผ่านมาฉันต้องการแปลงวินาทีเป็นชั่วโมง: นาที: รูปแบบวินาทีเหมือนที่$t = 494050 //secondsฉันต้องการพิมพ์แบบ137 h 14 m 10 sดังนั้นฉันจึงได้ฟังก์ชั่น php springf()ฉันแค่ค้างวินาที$tและecho sprintf("%02d h %s%02d m %s%02d s", floor($t/3600), $f, ($t/60)%60, $f, $t%60);ให้ฉัน137 h 14 m 10 s

ฟังก์ชั่น sprintf () มีประโยชน์มากถ้าเรารู้วิธีใช้งาน


2

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


2

กรณีการใช้งานที่ดีมากสำหรับการใช้ sprintf คือการแสดงรูปแบบตัวเลขที่มีเบาะและเมื่อผสมชนิดต่าง ๆ ในสตริง สามารถอ่านได้ง่ายขึ้นในหลาย ๆ กรณีและทำให้มันง่ายมากในการพิมพ์การนำเสนอที่แตกต่างกันของตัวแปรเดียวกันโดยเฉพาะอย่างยิ่งตัวเลข


2

การใช้ sprintf () ฟังก์ชั่นมากกว่าการต่อข้อมูลทั่วไปมีข้อได้เปรียบที่คุณสามารถนำการจัดรูปแบบประเภทต่างๆไปใช้กับตัวแปรที่จะต่อกันได้

ในกรณีของคุณคุณมี

$output = sprintf("Here is the result: %s for this date %s", $result, $date);

และ

$output = 'Here is the result: ' .$result. ' for this date ' .$date;

ให้เรารับ $result = 'passed'; date = '23rd';

การใช้การเรียงต่อกันแบบธรรมดาคุณจะได้ผลลัพธ์:

Here is the result: passed for this date 23rd

อย่างไรก็ตามหากคุณใช้sprintf()คุณจะได้รับผลการแก้ไขเช่น:

$output = sprintf('Here is the result: %.4s for this date %.2s',$result,$date);
echo $output;

เอาท์พุท:

Here is the result: pass for this date 23

2

sprintf()printf()ค่อนข้างคล้ายกับ หากคุณรู้printf()ในรายละเอียดแล้วsprintf()และยังvsprintf()ก็ไม่ยากที่จะเข้าใจ

หนึ่งในสิ่งที่แตกต่างsprintf()จากprintf()คือคุณจะต้องประกาศตัวแปรเพื่อจับเอาท์พุทจากฟังก์ชั่นในขณะที่มันไม่ได้พิมพ์ / echo อะไรโดยตรง ให้ดูตัวอย่างโค้ดต่อไปนี้:

printf("Hello %s", "world"); // "Hello world"

sprintf("Hello %s", "world"); // does not display anything

echo sprintf("Hello %s", "world"); // "Hello world"

$a = sprintf("Hello %s", "world"); // does not display anything

echo $a;// "Hello world"

หวังว่าจะช่วย


1

หนึ่ง "เอาท์พุท" หนึ่ง "ผลตอบแทน" หนึ่งที่เป็นหนึ่งในความแตกต่างที่สำคัญ

printf() เอาท์พุท

sprintf() ผลตอบแทน


0

คุณต้องระวังเมื่อใช้ sprintf ในลูป:

$a = 'Anton';
$b = 'Bert';
$c = 'Corni';
$d = 'Dora';
$e = 'Emiel';
$f = 'Falk';
$loops = 10000000;

$time = microtime(true);

for ($i = 0; $i < $loops; $i++)
{
    $test = $a . $b . $c . $d . $e . $f;
}

$concatTime = microtime(true) - $time;

$time = microtime(true);

for ($i = 0; $i < $loops; $i++)
{
    $test = "$a $b $c $d $e $f";
}

$concat2Time = microtime(true) - $time;

$time = microtime(true);

for ($i = 0; $i < $loops; $i++)
{
    $test = sprintf('%s %s %s %s %s %s', $a, $b, $c, $d, $e, $f);
}

$sprintfTime = microtime(true) - $time;

echo 'Loops: ' . $loops . '<br>';
echo '\'$a . $b . $c . $d . $e . $f\'' . ' needs ' . $concatTime  . 's<br>';
echo '"$a $b $c $d $e $f"' . ' needs ' . $concat2Time  . 's<br>';
echo 'sprintf(\'%s %s %s %s %s %s\', $a, $b, $c, $d, $e, $f)' . ' needs ' . $sprintfTime  . 's<br>';

ซึ่งนำไปสู่เวลาต่อไปนี้ (บนเครื่องโลคัลของฉันด้วย PHP 7.2):

ลูป: 10,000,000

'$ a $ b $ c $ d $ e $ f 'ต้องการ 1.4507689476013s

"$ a $ b $ c $ d $ e $ f" ต้องการ 1.9958319664001s

sprintf ('% s% s% s% s% s% s% s', $ a, $ b, $ c, $ d, $ e, $ f) ต้องการ 9.1771278381348s


0

ฉันใช้เพื่อส่งข้อความถึงผู้ใช้หรือฟังก์ชันการทำงานประเภท "สวย" อื่น ๆ เช่นถ้าฉันรู้ว่าฉันจะใช้ชื่อผู้ใช้

$name = 'Some dynamic name';

และมีหลายข้อความให้ใช้ในสถานการณ์นั้น (เช่นปิดกั้นหรือติดตามผู้ใช้รายอื่น)

$messageBlock = 'You have blocked %s from accessing you.';
$messageFollow = 'Following %s is a great idea!';

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

ลองคิดดูสิว่าอะไรดีกว่ากัน?

return $messageOne === true ? $name.'. Please use the next example' : 'Hi '.$name.', how are you?'

หรือ

$message = $messageOne === true ? 'Option one %s' 
: ($messageTwo === true ? 'Option Two %s maybe?' : '%s you can choose from tons of grammatical instances and not have to edit variable placement and strings');

return sprintf($message, $name);

แน่นอนว่ามันเป็นขั้นตอนพิเศษ แต่จะเกิดอะไรขึ้นถ้าการตรวจสอบตามเงื่อนไขของคุณทำสิ่งต่าง ๆ ที่เกี่ยวกับการทำงานอื่น ๆ แล้วใบเสนอราคาและการต่อท้ายจะเริ่มต้นในการเข้ารหัสตามหน้าที่

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