เริ่มต้นกับ Laravel – Migrations

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

เริ่มต้นเวลาเราจะปล้ำกับโปรเจ็ค PHP สักตัว สิ่งแรกคือการออกแบบเว็บซึ่งจะมีอยู่ 3 ส่วนหลักๆ 1.หน้าตา 2.ระบบ 3.ฐานข้อมูล ซึ่งเรื่องพวกนี้เป็นพื้นฐานอยู่แล้วเพื่อป้องกันการมั่วในงานที่ทำ หลายคนเลือกใช้ทั้งเขียน flowchart บางคน wireframing บางคนดิบๆ ลงกระดาษก็มี บางคนบินสูงทำเป็น Digital ไปหมด

วันนี้ผมจะข้ามไปเรื่องฐานข้อมูลก่อน เพราะในงานผมทำ มักจะมาทำฐานข้อมูลก่อนเสมอ เนื่องจาก

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

แน่นอนว่าถ้าคุณใช้ Framework ตัวอื่น คุณต้องเป๊ะระดับหนึ่งเพื่อแลกกับการเหนื่อยน้อยลงในภายหลัง แต่วันนี้เราจะใช้ Laravel ซึ่งมันมีเครื่องมือตัวหนึ่งช่วยลดเวลาขั้นตอนการ PDCA ของเรา (Plan-Do-Check-Adjust)

Laravel มีเครื่องมือชื่อ Migrations ซึ่งผมสรุปความหมายมันให้สั้นที่สุดคือ Version Control ของ Database ซึ่งอธิบายง่ายๆ ว่า มันช่วยเอาโค้ด PHP ของเราที่เขียนบน Schema Builder ไปสร้างเป็นฐานข้อมูลในฐานข้อมูลให้เสร็จ แล้วเรายังสามารถจะ rollback ย้อนกลับสิ่งที่เราทำไปก็ได้ ทำให้เราลดเวลาการแก้ไขได้มากโข สำหรับผมขอบอกว่ามันครบเอามากๆ

แน่นอนบทความนี้เป็นบทความแรก เราจะมีพูดถึงตั้งแต่การติดตั้ง Laravel เลย เสียดายว่าผมลองพิมพ์ไปแล้ว 10 นาที ค้นพบว่ามันปวดตับ ผมเลยลบแล้วไม่พิมพ์มันซะเลย  /ee งานนี้สำหรับใครอ่านอังกฤษไม่เป็น แนะนำไปฝากความหวังกับ http://laravel.in.th/ ซึ่งคงจะมีบทความคลอดเร็วๆ นี้

ผมจะข้ามไปการออกแบบฐานข้อมูลเลย ก่อนอื่นที่ต้องมีคือ Laravel ที่ติดลงเครื่องเราพร้อมกับตั้งค่าฐานข้อมูลแล้ว จากนั้นเรามาเริ่มกันเลย!

เปิด cli ของเครื่องท่าน ถ้าเป็น Windows ก็ Dos ถ้าเป็น Linux ก็ Shell อะไรก็ว่าไป แล้ว CD เข้าโฟลเดอร์ Laravel ของท่าน เริ่มต้นให้พิมพ์คำสั่ง

php artisan migrate:install

เพื่อสร้างตาราง laravel_migrations สำหรับเก็บข้อมูลการเปลี่ยนแปลงในการรัน migrate แต่ละครั้ง พูดชัดๆ มันคือฐานข้อมูลของ Version Control นั้นแหละ

ทีนี้ผมจะสร้างตารางมาตรฐานที่ทุกระบบมันควรมีคือตารางเก็บข้อมูลผู้ใช้งาน แน่นอนว่าชื่อตารางสำคัญควรอยู่ในรูป plural หรือพหูพจน์ เพราะอนาคตสำหรับคนใช้ Laravel ถ้าไม่ได้ลองใช้ Eloquent ORM ผมว่าเสียของมากๆ ดังนั้นเราจะมาจบกันด้วยชื่อว่า users (เรื่องนี้จริงๆ ไม่ fixed เราสามารถใช้ชื่ออะไรก็ได้ เพียงแต่ต้องเพิ่มโค้ดลงส่วน Model ไป 1 บรรทัด)

ใน cli ให้พิมพ์

php artisan migrate:make users

แล้วกด Enter ถ้าเจอข้อความ Great! New migration created! ก็คือสร้างเสร็จแล้ว เราจะได้ไฟล์สำหรับใส่โค้ดของ Schema Builder ลงไป ให้เปิด โฟลเดอร์ \application\migrations  เราจะเจอไฟล์ 2012_xx_xx_xxxxxx_users.php ซึ่ง x แทนด้วยตัวเลข ซึ่งคุณอาจเดาออก มันเป็นเลขวันที่และเวลา ดังนั้นมันจะแตกต่างออกไปตามเวลาการสร้างของแต่ละคน ให้เปิดไฟล์ เราจะเจอกับหน้าตาไฟล์แบบนี้

<?php

class Users {

	/**
	 * Make changes to the database.
	 *
	 * @return void
	 */
	public function up()
	{
		//
	}

	/**
	 * Revert the changes to the database.
	 *
	 * @return void
	 */
	public function down()
	{
		//
	}

}

จะมีสอง method คือ up กับ down โดย up ใช้ใส่โค้ดสำหรับตอนเราสร้างตาราง และ down ใช้ตอนถอนตาราง แต่จริงๆ มันมีความหมายคือการขึ้นหรือลงในการคุม Version ของฐานข้อมูล แน่นอนโค้ดการใส่คุณสามารถหาอ่านได้ที่ Schema Builder ดังนั้นผมจะแปะตัวอย่างที่ผมเขียนเป็นแนวทางให้

<?php

class Users {

	/**
	 * Make changes to the database.
	 *
	 * @return void
	 */
	public function up()
	{
		//Create table
		Schema::create('users', function($table)
		{
			//Set engine
			$table->engine = 'InnoDB';

			//Create fields
			$table->increments('id');
			$table->string('username', 64);
			$table->string('password', 64);
			$table->string('email', 64);
			$table->timestamps();

			//Create index
			$table->unique('username');
			$table->unique('email');
		});
	}

	/**
	 * Revert the changes to the database.
	 *
	 * @return void
	 */
	public function down()
	{
		//Drop table
		Schema::drop('users');
	}

}

ซึ่งถ้าอ่านแล้วผมว่าน่าจะเข้าใจกันนะครับ แต่จะมีจุดสังเกตคือไม่มีคำสั่งสร้างฟิลด์ id ซึ่งนั้นเพราะการสร้างฟิลด์ id จะถูกทำโดยอัตโนมัติอยู่แล้วในกรณีไม่มีการกำหนด primary key เนื่องจากมันเป็นพื้นฐานถ้าเราจะเขียน Eloquent ORM ซึ่งย้ำกว่าควรลองเขียน นอกนั้นการกำหนด increments นี้ควรต้องใส่ เพราะ primary key ที่ไม่ increments เองก็มีนะครับ บางคนเข้าใจ primary key มันต้อง auto increments ซึ่งมันผิด ในบางเคสผมเคยเอา hash md5 เป็น primary key มาแล้ว

อีกคำสั่งที่น่าสนใจและอาจจะงงๆ คือ

$table->timestamps();

ซึ่งอันนี้จะทำให้เราสร้างฟิลด์ created_at กับ updated_at เมื่อเราใช้คู่กับ Eloquent ORM มันจะเพิ่ม timestamp เมื่อเราเพิ่ม record ใหม่ลง created_at และแก้ไข updated_at เมื่อยามที่เราแก้ไข record เมื่ออ่านอย่างนี้คุณจะจินตนาการได้เลยว่าคุณไม่ต้องมีฟิลด์ว่าสมัครสมาชิกวันไหน หรือการแก้ไขโปรไฟล์ล่าสุดวันไหน เพราะมันจัดการตรงนี้ให้เสร็จ

สุดท้ายเราได้ 1 ตารางแล้ว คุณสามารถรัน

php artisan migrate

เพื่อสั่งเพิ่มตารางลงฐานข้อมูลได้เลย และถ้าคุณไม่พอใจ อยากแก้ไขตั้งแต่ต้น ก็แค่พิมพ์

php artisan migrate:reset

ในฐานข้อมูลคุณจะกลับมาตั้งต้น ตารางที่เคยถูกเพิ่มจะโดน drop ทิ้ง ซึ่งจากเท่านี้คุณก็สามารถทำการปรับเปลี่ยนแก้ไขได้อีกหลายครั้ง และไม่ต้องจับ phpmyadmin ไปอีกนาน

จริงๆ คุณยังทำลูกเล่นกับ Schema Builder ได้อีกเยอะ เสียดายผมหมดแรงดังนั้นไว้ต่อวันหลังถ้าไม่ลืม

/bye

Auto restart faxgetty when modem crash

Hi everybody in our world. I hope you have good health. Today I will paste my simple php code that I used in company server. My server got some problem that I don’t know what is source of this problem. I use Hylafax with Avantfax. Both of them update lasted version on Ubuntu 10.10. I know only it’s about segfault. I found some log at /var/log/messages and I don’t know anymore.

/…

I found php script in some website but I use 2 modem. (1 external 1 internal) That php script didn’t work so I modified script. It’s very simple version. I don’t put any license to it so you can modify it freely.

/ee

<?php
/**
* Check if faxgetty runs and if not restart the service
* It's about segfault. /var/log/messages
*
* For two modem by EThaiZone.com
*/

$process='faxgetty'; //process
$command="ps -Al -cmd| grep ".$process; //command !!!

ob_start();
passthru($command); //execute command
$result=ob_get_contents();
ob_end_clean();

if(preg_match('#'.$process.'\r?\n.+'.$process.'#', $result))
{
	echo "No problem. Faxgetty run fine.\n"; //OK
}
else
{
	echo "Restart hylafax\n";
	exec("service hylafax restart");
}

?>

Save it and run it via cronjob. I recommend to run every seconds because it don’t cause load on cpu that should worry. In my cron I put this.

* * * * *   php -q /checkfaxgetty.php

I hope this’s useful to you.  /bye

เคล็ดลับการอัพไฟล์ผ่าน FTP ที่ดีและได้ไฟล์ถูกต้อง

บทความนี้จะไม่สอนถึงขั้นตอนพื้นฐานการอัพ FTP และผมไม่รับตอบคำถาม เพราะถือว่าผู้อ่านต้องเคยอัพไฟล์ FTP และมีความเข้าใจในระบบนี้มาบ้างแล้ว

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

##############################

เกริ่นนำ

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

เข้าตรงประเด็นเลยคือ การตั้งโหมดชนิดการรับส่งผ่าน FTP นั้นในโปรแกรม FTP ทุกตัวเลยจะมีการตั้งอยู่ 3 แบบคือ
1. Ascii ใช้สำหรับส่งไฟล์ที่เป็น text based เช่น txt html php js css บลาๆ – พูดง่ายๆ คือเปิดอ่านด้วย notepad แล้วคุณอ่านออก มันคือ text based
2. Binary ใช้สำหรับส่งไฟล์แบบดิบๆ (ภาษาอังกฤษใช้คำว่า raw file) เช่น jpg png mp3 zip rar บลาๆ – พูดง่ายๆ คือเปิดอ่านด้วย notepad แล้วคุณจะงงกับมัน
3. Auto เป็นส่วนที่ให้โปรแกรมตัดสินใจเองว่าไฟล์ไหนจะให้ส่ง Ascii อันไหน Binary

แน่นอนจากที่พูดมา ตัวที่ดูเข้าท่าก็คือ Auto และ Auto จะจัดสรรให้ php ไปลงที่ Ascii ซึ่งมันก็ดูเข้าหลักเกณฑ์ปกติ

ข้อเท็จจริง

ในความเป็นจริงคือ PHP สมควรอัพด้วยโหมด Binary ถามว่าทำไม? มันจะถูกตอบด้วยเหตุผลเหล่านี้

1.  PHP เป็นโค้ดโปรแกรม หลายคนต้องการความแน่นอนว่าอัพแล้วไฟล์ไม่ผิด วิธีเช็คที่ง่ายที่สุดคือคือการตรวจขนาดไฟล์ แต่ปรากฎว่าไฟล์ PHP เมื่ออัพผ่าน Ascii มักจะผิดขนาดบ่อยครั้ง
และเฉพาะกรณีอัพจาก Windows ไปลงโฮส Linux Unix มักจะมีการลบ CR (carriage return) ถ้าพูดในภาษาคนเขียน PHP คือ มันจะเปลี่ยยน \r\n เป็น \n อย่างเดียว ทำให้การเช็คขนาดไฟล์ว่าเราอัพไปถูกไหม หรือจะเช็ค MD5 ในกรณีคนที่บ้าพาว มันไม่สามารถทำได้เลย จำเป็นต้องใช้การ compare code อย่างเดียว ซึ่งมันเว่อร์ดีแท้
ขอแถม ผมไม่เคยเห็น Web server ในไทยใช้พวก OSX แต่อยากบอกว่า OSX ดันใช้ \r อย่างเดียวล่ะ ที่เหลือไปคิดเอาเอง -*-

2. ในกรณีไฟล์ PHP ที่โดนเข้ารหัสเพื่อป้องกัน เน้นเฉพาะกับ 2 ตัวคือ Zend และ Ioncube ทั้งสองตัวนี้เมื่อคุณอัพด้วยโหมด Ascii รับรองว่าคุณจะปวดหัวแท้ เพราะการเข้ารหัสของทั้งสองตัวจะทำให้โค้ดอ่านไม่ออก และมีความเป็นไปได้ที่จะผิดพลาดได้สูงกว่าไฟล์ PHP ที่ไม่ได้เข้ารหัส (แน่นอนรวมทั้งไฟล์ PHP ที่ผ่าน eAccelerator ด้วย)

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

เคล็ดลับวิธีทำ

แล้วจะรออะไรกันล่ะ มาตั้ง Binary Mode กันดีกว่า! วิธีตั้งแสนง่ายมาก ที่จะบอกนี้เป็นวิธีนี้สำหรับ FileZilla เท่านั้น! ดังนั้นโปรแกรมอื่นก็หาทางกันเอาเองนะ

สำหรับเมนูอังกฤษ

Posted Image

สำหรับเมนูไทย

Posted Image

ที่เหลือก็อัพไฟล์ตามขั้นตอนปกติครับ จบ!  /XD

ข้อควรระวัง ภาพนี้มาจาก FilaZilla v3.5.3 ในอนาคตอาจมีการเปลี่ยนแปลงได้

ปล. ใครใช้โปรแกรม FTP โปรดระวังโดนแฮกเว็บ ผมเจอเคสพวกนี้มาเยอะ เชื่อเถอะ
ปล2. บทความนี้สงวนลิขสิทธิ์คัดลอกได้แต่ต้องทำลิงก์กลับมาต้นฉบับ และห้าม Hotlink ภาพไป ต้องใช้การอัพโหลดไปไว้ที่อื่น ถ้าทำผมก็จะทำเหมือนกรณีที่ Blognone เคยโดน Hotlink เลย …. เหอๆ