โจทย์คือการ import ข้อมูลจาก excel เข้าไปเก็บใน database ซึ่งมันก็ไม่ซับซ้อนอะไรถ้าคำนำหน้านาม, ชื่อ, ชื่อกลาง, นามสกุลมันไม่อยู่ในช่องเดียวกัน แต่ในตารางต้องการให้แยกไว้คนละฟิลย์เพื่อความสะดวกในการดึงข้อมูล
ดูง่ายๆ แค่ตัดสตริงค์ตามช่องว่างก็น่าจะได้ แต่อย่างชื่อผม นาย พิชญ์ พันธุ์สนิท และชื่อ นาง ธิติมา แอน ประทุมทิพย์ ต่างกันคือ ตัดออกมาได้อาร์เรย์สมาชิก 3 ตัว และ 4 ตัว ก็เขียนเงื่อนไขได้ง่ายๆ ถ้ามี 4 ตัวก็แสดงว่ามี ชื่อกลาง
title = นาย
firstname = พิชญ์
middlename =
lastname = พันธุ์สนิท
และ
title = นาง
firstname = ธิติมา
middlename = แอน
lastname = ประทุมทิพย์
เขียน if (count($temp) == 4) ก็ได้แล้ว
แต่อย่าง ว่าที่ ร.ต.(หญิง) เต็มศิริ วีรสุข ถ้าใช้วิธี
1 | list($title, $firstname, $middlename, lastname) = explode( ' ' , 'ว่าที่ ร.ต.(หญิง) เต็มศิริ วีรสุข' ) |
แล้วออกมาเป็น
title = ว่าที่
firstname = ร.ต.
middlename = (หญิง)
lastname = เต็มศิริ
คงไม่งาม และบางราชชื่อไม่มีคำนำหน้านาม เช่น ( hr ผู้น่ารัก )
โชคดีที่มีคำนำหน้านามไม่เยอะเพราะฉะนั้นใช้วิธีใส่ในอาร์เรย์แล้วเอาไป search หาเอาก็ได้
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | <! doctype html> < html > < head > < meta charset = "utf-8" > < title >แบ่งชื่อ นามสกุล คำนำหน้านาม</ title > </ head > < body > <? php $names = [ 'ซาร่า มาลา กุล เลน ณ อยุธยา', 'นพ.เหรียญทอง แน่นหนา', 'นักเทคนิคการแพทย์ภาคภูมิ เดชหัสดิน', 'นางธิติมา แอน ประทุมทิพย์', 'นายพิชญ์ พันธุ์สนิท', 'ว่าที่ ร.ต.(หญิง) เต็มศิริ วีรสุข', ]; $titles = [ 'นพ.', 'นักเทคนิคการแพทย์', 'นาง', 'นาย', 'ว่าที่ ร.ต.(หญิง)', ]; $results = []; foreach ($names as $no => $name) { $temp = str_replace($titles, '<> ', $name); $temp = mb_ereg_replace('/\s+/', '\s', $temp); $temp = array_values(array_filter(explode(' ', $temp))); if ($temp[0] == '<>') { $results[$no]['title'] = substr($name, 0, strpos($name, $temp[1])); } else { $results[$no]['title'] = ''; array_unshift($temp, ''); } $results[$no]['firstname'] = $temp[1]; if (count($temp) == 4) { $results[$no]['middlename'] = $temp[2]; $results[$no]['lastname'] = $temp[3]; } else { unset($temp[0], $temp[1]); $results[$no]['middlename'] = ''; $results[$no]['lastname'] = implode(' ', $temp); } } echo '< pre >', print_r($results, true), '</ pre >'; ?> </ body > </ html > |
ผลลัพธ์ คือ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | Array ( [0] => Array ( [title] => [firstname] => ซาร่า [middlename] => [lastname] => มาลา กุล เลน ณ อยุธยา ) [1] => Array ( [title] => นพ. [firstname] => เหรียญทอง [middlename] => [lastname] => แน่นหนา ) [2] => Array ( [title] => นักเทคนิคการแพทย์ [firstname] => ภาคภูมิ [middlename] => [lastname] => เดชหัสดิน ) [3] => Array ( [title] => นาง [firstname] => ธิติมา [middlename] => แอน [lastname] => ประทุมทิพย์ ) [4] => Array ( [title] => นาย [firstname] => พิชญ์ [middlename] => [lastname] => พันธุ์สนิท ) [5] => Array ( [title] => ว่าที่ ร.ต.(หญิง) [firstname] => เต็มศิริ [middlename] => [lastname] => วีรสุข ) ) |
อธิบาย
1 | $temp = str_replace ( $titles , '<> ' , $name ); |
เปลี่ยนคำนำหน้านามเป็นตัวอื่นก่อน
1 | $temp = mb_ereg_replace( '/\s+/' , '\s' , $temp ); |
เอาสเปซที่มีมากกว่า 1 ตำแหน่งแทนที่ด้วยช่องว่าแค่ 1 ตำแหน่งก็พอ
1 | $temp = array_values ( array_filter ( explode ( ' ' , $temp ))); |
แบ่งข้อมูลออกเป็นส่วนๆ โดย array_values(array_filter()) จะทำให้อินเด็กซ์ของอาร์เรย์เป็นไปตามลำดับ
1 | array_unshift ( $temp , '' ); |
ถ้าไม่มีคำนำหน้านามก็ใส่ให้มัน ลำดับอาร์เรย์จะได้ไม่เคลื่อนไป
1 | $results [ $no ][ 'lastname' ] = implode( ' ' , $temp ); |
เพราะว่าบางคน นามสกุล จะมีช่องว่างจำนวนมาก เช่น มาลา กุล เลน ณ อยุธยา และถ้าแบ่งข้อมูลผิด ผลลัพธ์ที่ได้ก็ไม่น่าเกลียดเท่าไหร่