jQueryTips by Tee++; Coding like playing a piano. Sat, 19 May 2012 05:59:16 +0700 OSCool http://jquerytips.oscool.com/ jQueryTips jQueryTips jQueryTips wrote a new story "ใครๆ ก็มี Utils เอางี้เราเพิ่ม Utils ให้กับ CodeIgniter กันบ้าง". Wed, 21 Mar 2012 19:08:26 +0700 http://jquerytips.oscool.com/blogs/view/3396 http://jquerytips.oscool.com/blogs/view/3396 jQueryTips jQueryTips พอดีช่วงนี้ผม กำลังหา Solution Framework ที่ทำงานเป็นทีมได้สะดวกๆ แล้วก็ไม่ทำให้โคด "เสียทรง" ในระหว่างที่กำลังพัฒนา รวมไปถึงไม่ต้องเสียเวลา Learning กับ Framework ตัวใหม่ๆ ซึ่ง ก่อนหน้านี้ก็ได้ลองเพิ่ม HMVC ให้กับ CI อันที่จริงตัวนี้ผมลองเล่นมานานแล้ว แต่ว่าเมื่อก่อน มันทำแปลกๆ โคดไม่เข้ากับระบบ โดยรวม ทำให้เวลา CI เปลี่ยน Version ต้องมาแก้ไอ้นี่กันตลอด แต่พอวันนี้ได้ไปดูอีกที เห็นว่า เปลี่ยนมาเขียนในรูปแบบ 3Party ของ CI (จริงๆ มันแค่ยืม Folder มาเก็บ) รวมไปถึงยัง extend controller ออกมาได้เหมือนเดิม ก็เลยลองใช้ดู พบว่าใช้ได้พอสมควร ก็เลยเอามาใส่

แต่เรื่องที่วันนี้จะมาเขียนไม่ได้เกี่ยวกับ HMVC ตัวนี้เลย เพราะว่าอันนี้ ใครเอาไปลองก็ทำได้ง่ายๆ วิธีติดตั้งเค้าก็เขียนมา ไม่มีอะไรซับซ้อน 

ส่วนเรื่องที่จะเขียนจะเป็นเรื่องเกี่ยวกับการ รวมกลุ่ม ของ functions ให้ออกมาในรูปแบบของ utilities.....

เกริ่นซะหน่อยเดี๋ยวจะงง

ถ้าเกิดมีใครได้ลอง PHP Framework เดี๋ยวนี้ มักจะพบว่า แต่ละตัวก็จะมี utils ซึ่งบางตัวก็อาจจะใช้ชื่อต่างจากนี้ อันที่จริง มันไม่ใช่อะไร แต่เป็นการเขียน helpers ให้อยู่ในรูปแบบ ของ class ซึ่งจัมีประโยชน์ในด้าน naming ของโคด ทำให้ จัดกลุ่มได้อย่างสวยงาม ยกตัวอย่างเช่น ถ้าผมจะเขียนเกี่ยวกับเรื่อง Path ใน CodeIgniter ผมก็อาจจะไป extend url_helper ออกมา ให้เป็น MY_url_helper แล้วเขียน function เติมลงไป ซึ่งจริงๆ แล้วมันก็ไม่มีอะไรเสียหาย แต่ว่า ถ้าเกิดมีใครไป ตั้งชื่อ "แปลกๆ" อาทิเช่น user_info() ใน  ไฟล์นี้ล่ะก็ รับรองได้ ต้องไล่โคดกันยาวววววว

แต่ถ้าผมเปลี่ยนมาเขียนในรูปแบบ

<?php

class CIUrl {

  public static function getAssetsUrl($uri='')
  {
    return site_url('assets/'.$uri);
  }

  public static function getThumbnailUrl($uri='')
  {
    return "......";
  }

}

เวลาเรียกใช้ ก็เรียกเหมือน helper ปกติ แบบนี้

<?php

CIUrl::getAssetsPath()

 

ทีนี้พอเราเห็น คำว่า CIUrl ก็จะรู้ได้เลยว่าต้องไปหาที่  /utils/CIUrl.php ซึ่งใช้เวลาสั้นกว่ามาก อันที่จริงแล้วผมจัดกลุ่มด้วยตัวเอง ผมจะแบ่งออกเป็น

helpers = function  ดิบๆ เช่นพวกทำงานกับ string, numeric หรือเรื่องพื้นๆ

utils = function ที่ต้องทำงานร่วมกับ model ในบางครั้ง

อันที่จริงแล้วถ้าผมจะเขียนแบบนี้ ผมไปเขียนใน helpers ก็ได้ แล้วก็เรียก load helper ตามปกติ แต่ว่ามันจะไม่ได้ในเรื่องของ naming ชื่อไฟล์ แล้วก็ ดูไม่เป็นสัดส่วน เหมือนกับไปหักดิบ Framework ที่เค้าออกแบบมา แล้ว

ดังนั้น ประเด็นวันนี้ที่เราจะมาทำกันก็คือ

1. เพิ่ม utils ให้กับ CI

2. ทำตัว load เฉพาะ ให้กับ utils

3. ทำส่วน  autoload ให้กับ utils

มาๆ เริ่มกันเลย ข้อที่ 1

อันนี้โครตง่าย ไปสร้าง folder utils ที่

/application/utils เป็นอันเรียบร้อย

 

ข้อที่ 2, 3 อันนี้หัวใจเลยครับ ไป extend loader  ออกมาไว้ที่

/application/core/MY_Loader.php

แล้วเติมส่วน load util, utils, autoload เข้าไปซะหน่อย ตามโคดข้างล่างนี่ (ขอไม่อธิบาย นะ ก็ Copy มาจาก ตัว load helper นั่นแหละ)

<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

/**
 * MY_Loader Class
 *
 * Append method to parent
 *
 * @package		CodeIgniter
 * @subpackage	Libraries
 * @author		Tee++;
 * @category	Loader
 * @link		http://www.jquerytips.com
 */
class MY_Loader extends CI_Loader {
	
	/**
	 * List of paths to load utils from
	 *
	 * @var array
	 * @access protected
	 */
	protected $_ci_utils_paths = array();
	/**
	 * List of loaded utils
	 *
	 * @var array
	 * @access protected
	 */
	protected $_ci_utils = array();
	
	/**
	 * Override Initialize 
	 *
	 * This method is add utlis config
	 *
	 * @param 	array
	 * @return 	void
	 */
	public function initialize($controller=null)
	{
		parent::initialize($controller);
		
		// config utils path and check autoloading
		$this->_ci_utils_paths = array(APPPATH, BASEPATH);
		$this->_ci_utils_autoloader();
	}
		
	/**
	 * Load Util
	 *
	 * This function loads the specified util file.
	 * This is core function to really file.
	 *
	 * @access  protected
	 * @param	mixed
	 * @return	void
	 */
	public function util($utils = array())
	{
		foreach ($this->_ci_prep_filename($utils, 'CI', true) as $util)
		{
			if (isset($this->_ci_utils[$util]))
			{
				continue;
			}

			$ext_util = APPPATH.'utils/'.config_item('subclass_prefix').$util.'.php';

			// Is this a util extension request?
			if (file_exists($ext_util))
			{
				$base_util = BASEPATH.'utils/'.$util.'.php';

				if ( ! file_exists($base_util))
				{
					show_error('Unable to load the requested file: utils/'.$util.'.php');
				}

				include_once($ext_util);
				include_once($base_util);

				$this->_ci_utils[$util] = TRUE;
				log_message('debug', 'util loaded: '.$util);
				continue;
			}

			// Try to load the util
			foreach ($this->_ci_utils_paths as $path)
			{
				if (file_exists($path.'utils/'.$util.'.php'))
				{
					include_once($path.'utils/'.$util.'.php');

					$this->_ci_utils[$util] = TRUE;
					log_message('debug', 'Util loaded: '.$util);
					break;
				}
			}

			// unable to load the util
			if ( ! isset($this->_ci_utils[$util]))
			{
				show_error('Unable to load the requested file: utils/'.$util.'.php');
			}
		}
	}
	
	/**
	 * Load Utils
	 *
	 * This is simply an alias to the above function in case the
	 * user has written the plural form of this function.
	 *
	 * @param	array
	 * @return	void
	 */
	public function utils($utils) 
	{
		foreach ($utils as $_util) $this->util($_util);	
	}

	
	/**
	 * Prep filename
	 * Override from parent
	 *
	 * This function preps the name of various items to make loading them more reliable.
	 *
	 * @param	mixed
	 * @param 	string
	 * @param   bool
	 * @return	array
	 */
	protected function _ci_prep_filename($filename, $extension, $opposite=false)
	{
		if ($opposite == false) {
			return parent::_ci_prep_filename($filename, $extension);
		}
		
		// opposite prep in front
		if ( ! is_array($filename))
		{
			return array($extension.ucfirst(str_replace('.php', '', str_replace($extension, '', $filename))));
		}
		else
		{
			foreach ($filename as $key => $val)
			{
				$filename[$key] = $extension.ucfirst(str_replace('.php', '', str_replace($extension, '', $val)));
			}

			return $filename;
		}
	}
	
	/**
	 * Utils Autoloader
	 *
	 * The config/autoload.php file contains an array that permits sub-systems,
	 * utils to be loaded automatically.
	 *
	 * @param	array
	 * @return	void
	 */
	private function _ci_utils_autoloader()
	{
		if (defined('ENVIRONMENT') AND file_exists(APPPATH.'config/'.ENVIRONMENT.'/autoload.php'))
		{
			include(APPPATH.'config/'.ENVIRONMENT.'/autoload.php');
		}
		else
		{
			include(APPPATH.'config/autoload.php');
		}

		if ( ! isset($autoload))
		{
			return FALSE;
		}

		// auto load utils 
		if (isset($autoload['utils']) AND count($autoload['utils']) > 0)
		{
			$this->utils($autoload['utils']);
		}
	}
	
}

 

 ** ส่วน autoload ที่ไม่  override master มาแก้เพราะว่า master มันเป็น private function แล้วก็ยังไง $autoload มันก็ไม่มาอยู่ดีไม่อยากไปแก้ core มันเลยใช้วิธีเขียนซ้ำเอาครับ

 

ที่นี้เราลองมาเขียน util กันงานๆ สักตัวนึงที่

application/utils/CIUser.php

<?php

class CIUser {

	public static function getInfo($id)
	{
		$data = array(
			'id'       => 1,
			'name'     => "Pattanai",
			'nickname' => "Tee++;",
			'website'  => "http://www.jquerytips.com"			
		);
		return new CIUserAttibutes($data);
	}
	
	public static function getAuthInfo()
	{
		return "Get User Who Logged In Info.";
	}
	
}

class CIUserAttibutes {

	private $_user_info;
	
	public function __construct($user_info)
	{
		$this->_user_info = $user_info;
	}
	
	public function getAttrs()
	{
		if (is_array($this->_user_info)) {
			return $this->_user_info;
		}
		return;
	}
	
	public function getAttr($attr)
	{
		if (array_key_exists($attr, $this->_user_info)) {
			return $this->_user_info[$attr];
		}
		return;
	}
	
}

 

 แล้วเราลองมาเรียกใช้ใน Controller กันดู

	public function test()
	{	
		$this->load->util('user');
		echo CIUser::getInfo(1)->getAttr('website');
	}

 

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

/application/config/autoload.php

/*
| -------------------------------------------------------------------
|  Auto-load Utils
| -------------------------------------------------------------------
| Prototype:
|
|	$autoload['utils'] = array('user');
|
*/

$autoload['utils'] = array('user');

 

เท่านี้ก็เป็นอันจบ เราก็จะได้ utilities มาใช้ง่ายๆ เหมือน Framework อื่นๆ กันแล้วล่ะครับ

 

]]>
jQueryTips wrote a new story "แนะนำ JS.Class (A JavaScript class library)". Thu, 01 Mar 2012 00:01:07 +0700 http://jquerytips.oscool.com/blogs/view/3305 http://jquerytips.oscool.com/blogs/view/3305 jQueryTips jQueryTips JS.Class

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

คือจากหน้าเว็บมัน มันบอกว่า ตัวเองเป็น ชุดเครื่องมือ สำหรับสร้างโปรแกรม JavaScript ในเชิงวัตถุ ที่ได้อิทธิพลมาจาก ภาษา Ruby แล้วก็ทำงานได้ ทั้งฝั่ง Client แล้วก็ Server

พอดี ผมไปลองเขียนเล่นๆ มาดูนิดหน่อย เห็น Syntax สวยงามน่าใช้ เป็นรูปแบบดี โคดไม่เลอะเทอะ อาจจะหยิบ ไปใช้ร่วมกับ PhoneGap หรือ Ti ได้ ก็เลยลองสักหน่อย ได้ผลมาตามข้างล่างนี้แหละครับ

ใครสนใจก็ลองไปอ่าน Manual แล้วก็เล่นดู ถ้าเล่นแค่ แบสิค ตามหน้าเว็บมันแบบผม มันก็ไม่ยากหรอกครับ อิอิ

ที่เหลืออยู่ที่ว่าจะเอาไปประยุกต์ใช้ยังไง

นอกจากนี้ก็ยังเจอ ไอ้ตัวที่คล้ายๆ กันอีกตัว แต่ยังไม่มีเวลาลองเลย เอาลิ้งก์มาแปะไว้ก่อนละกัน เผื่อจะมีคนสนใจ

Joose

ไปล่ะครับ สั้นๆ ง่ายๆ

]]>
jQueryTips wrote a new story "PHP กับ OOP มาปูพื้นฐานกันเสียใหม่ก่อน". Wed, 29 Feb 2012 14:38:50 +0700 http://jquerytips.oscool.com/blogs/view/3302 http://jquerytips.oscool.com/blogs/view/3302 jQueryTips jQueryTips สวัสดี สวีดัด ไม่ได้พบเจอกันนาน เป็นไงกันบ้าง หวังว่าคงสบายดีกันทุกคน ว่างๆ ก็ไปทักทายกันที่ Fan Page ได้นะครับ

วันนี้จะมาคุยถึงเรื่อง Object-oriented programming (OOP) ในภาษา PHP กันซะพอหอมปากหอมคอ

ก่อนอื่นนั้น เท่าที่สังเกตุส่วนมาก Developers สมัยนี้แทบจะเรียกว่า เขียนโปรแกรมแบบ OOP "เป็น" กันหมดแล้ว เพราะว่าสมัยนี้ Framework หรือว่า Components ต่างๆ นั้นถูกผลิตมาแบบ OOP เป็นเสียส่วนใหญ่ จริงๆ ก็เรียกได้ว่า แทบจะ 100% เลยทีเดียว ทั้ง Yii, CI, Zend, etc. ซึ่งแน่นอนเราก็หลักเลี่ยงที่จะใช้มันไม่ได้เสียด้วย ทีนี้พอ Developers ใช้ของพวกนี้บ่อยๆ เข้าจนชำนาญ ก็พาลคิดไปว่า กรูนี่เขียน OOP "เป็น" แต่ไอ้คำว่า เป็น นี่ต้องมาดูกันอีกทีว่าเป็น แค่นั้น เพราะว่าของพวกนี้ มันต้องมี Basic ครับ ไม่สามารถกระโดดข้ามขั้นไปได้

เพราะว่าถ้า Basic ไม่แน่น ขาดความเข้าใจพื้นฐาน มันก็จะพาล ไปเขียนโคดแบบ Procedural ใน OOP Framework เสียฉิบ ไล่มาตั้งแต่ Keywords ของ OOP เลย ต้องทำความเข้าใจให้ครบถ้วน อาทิเช่น

interface + implements ใช้ทำอะไร

abstract class คืออะไร

public, private, final, protected  ต่างกันยังไง

static ใช้ทำอะไร ต้องใช้แบบไหนจึงจะเหมาะสม

พอไล่เรื่อง keywords จบก็ควรจะศึกษาเรื่อง Design Patterns ต่อ เพราะว่า การเขียน oop ไม่ใช่มีแบบเดียว ต้องเลือกเขียนให้เหมาะสมกับงานที่จะใช้งาน

โดยส่วนนี้ผมขออ้างอิงจากบทความของ คุณ Robert Gonzalez (ชื่อแม่งเหมือนนักมวยเลย) ซึ่งเขียนได้น่าสนใจมากๆลองอ่านดูนะครับ

OOP Design Patterns for PHP

 

หลังจากทำความข้าใจกับ Patterns ต่างๆ ได้ ทีนี้เวลาเราเจอกับ โจทย์ เราก็จะเลือก คำตอบที่ถูกต้องกับงานได้ครับ อาทิเช่น

ผมมีโจทย์ที่ต้องเขียน ติดต่อกับ Database ซึ่งโจทย์ผม บอกว่า ผมต้องติดต่อกับฐานข้อมูลได้ทั้งหมด ผมก็จะออกแบบ Class ได้ถูกต้องว่า Design Pattern มันต้องเป็นแบบ Factory Design

เหมือนกับว่า ผมเป็นโรงงาน ขนม ไม่ว่า วัตถุดิบน้ำตาลผมมาจาก โรงงานแถวภาคไหน ผมก็ต้องผลิตขนมชนิดเดิมออกมาให้ได้ โดยใช้เครื่องจักรตัวเดิม

ถ้าเปรียบกับโจทย์ก็คือ ไม่ว่าผมจะใช้ Database อะไร Output ผมต้องออกมาเหมือนเดิม โดยไม่เปลี่ยน วิธีการเขียนติดต่อ เปลี่ยนแค่ adapter บางตัว ซึ่งอยู่ภายใน Factory ผมอีกที

ซึ่ง Class แบบนี้เป็น รูปแบบ OOP ที่เขียนลำบากแต่ว่าคุ้มค่ามากที่จะเขียน ตัวอย่างงานที่ต้องใช้ Class แบบนี้ก็คือ

1. Database Drivers

2. Hub Payment Gateways

3. Encryption

4. Caching

5. Hub SMS Gateway

แล้วก็อีกเยอะครับ, ทำไมต้องใช้แบบนี้ ??

อืมม์ ลองนึกตามดูครับ เอาเป็นเรื่อง Gateway ละกัน โจทย์ของผมมีว่า ผมต้องการทำระบบ คิดเงินออนไลน์ แต่ว่า Gateway ผมจะใช้แม่งทุกตัวเลย ตั้งแต่ Paypal, Google Checkout, 2Checkout ทีนี้ ถ้าผมต้องมาเขียน if else ในโปรแกรมผมแบบว่า

<?php

switch ($gateway)
{
  case 'paypay' :

    break;
  case 'gg_checkout' :

    break;
  case '2checkout' :
    break;
}

?>

 

ซึ่ง โคดผมก็คงจะดูวุ่นวายแบบนี้หลายจุด มาก เพราะว่า Gateway ต้องมีทั้ง ขาส่ง แล้วก็ขารับที่ เป็น Feed Data ส่งกลับมา if...else แบบนี้เวลาเพิ่ม Gateway ทีก็ต้องมาไล่แก้กันบานเยอะ

แต่ถ้าผมเขียน Class แบบ Factory มาใช้งาน ผมก็จะเขียนแค่

<?php

$pay = Payment::factory('paypal', $config);
$pay->redirect();

if ($pay->isSuccess()) {
}

if ($pay->isCanceled()) {
}

if ($pay->isPostedBack()) {
}

?>

 

แบบนี้เวลาผมเพิ่ม adapter ตัว งานที่เขียนก็แทบไม่ต้องแก้อะไรเลย

ด้านล่างนี้เป็นตัวอย่าง Class Gateway ที่ผมเขียนใช้เอง ลองโหลดไปดูเล่นๆ ได้ครับ แต่ว่ามันยังไม่ สมบูรณ์ดีในบาง Adapter นะครับ

https://github.com/teepluss/jPayment-Gateway

เอาล่ะๆ เริ่มขี้เกียจอีกแล้ว

ทีนี้เราลองมาดูตัวอย่างบทความดีๆ ของคนอื่นที่พูดถึงเรื่อง OOP Design Patterns กันบ้างนะครับ

http://www.ibm.com/developerworks/library/os-php-designptrns/

 

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

]]>
jQueryTips wrote a new story "ประกาศข่าวสารจาก Admin". Tue, 07 Feb 2012 00:24:28 +0700 http://jquerytips.oscool.com/blogs/view/3255 http://jquerytips.oscool.com/blogs/view/3255 jQueryTips jQueryTips วันนี้มาจั่วหัวแปลกๆ ไม่ได้มีอะไรพิเศษ หรือมี บทความสาระสำคัญอะไร มาอัพเดท แต่แค่จะมาบอกว่า บล็อกที่มัน ไม่อัพเดทเลย เพราะ Admin ขี้เกียจจริงๆ 555++

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

ตอนนี้ก็เสือกไปจดโดเมน onDeviceReady.com มาอีก คิดว่าจะเอามาเขียนเกี่ยวกับ Mobile Hybrid App (ไม่รู้คิดได้ไง ขี้เกียจขนาดนี้ สงสัยตอนคิด กรูจะเมา 555)

ก็เลยมาประกาศให้รู้โดยทั่วกันว่า บล็อกนี้อ่ะ มันไม่อัพเดท ง่ายๆ หรอกนะ นอกจากจะ อยากเขียนเรื่องอะไร มากๆๆๆ จนตัวขี้เกียจมันหลุดไปอ่ะแหละ

ต่อจากนี้ ถ้าจะเขียน ก็คงเป็นแบบ โพสต์ลง Facebook.com jQueryTips Fanpage นี่แหละ เล่นง่ายๆ ไปเลยกรู ยังไงก็ฝาก Page นี้ด้วย แล้วก็ถ้าว่างๆ ก็ไปคุยเล่นกันที่ Page ได้ไม่ซีเรียสๆ

สวัสดี (จบแบบหนังไทย โบราณแม่งเลยนี่)

]]>
jQueryTips wrote a new story "JSFIDDLE สุดยอด Tools สำหรับการ Debug การเขียนตัวอย่างโคด". Thu, 22 Dec 2011 01:07:13 +0700 http://jquerytips.oscool.com/blogs/view/3147 http://jquerytips.oscool.com/blogs/view/3147 jQueryTips jQueryTips

JSFIDDLE เป็น Tools สะดวกมากๆ สำหรับเขียน เทสต์ Script หรือว่า ส่งต่อตัวอย่าง หรือว่าจะประยุกต์ทำอะไรก็แล้วแต่

โดยที่ Tools ตัวนี้จะแบ่ง กล่องเริ่มต้นมาให้เรา ทั้งหมด 4 กล่อง แบ่งเป็น

HTML

CSS

JavaScript

Result

โดยที่เราสามารถเขียนสามารถเขียนโคด ตามแต่ละส่วน แล้วผลลัพธ์ก็จะออกมาที่ ส่วน "Result" ที่สำคัญ Tools ตัวนี้ ยังอนุญาติให้เรา Load พวก JS Framework ต่างๆ เข้าไปเพื่อทำการเทสต์ร่วมได้ด้วย โดยที่เราจะใช้ Sources ที่เค้าเตรียมมาให้ หรือว่าจะ link ตรงเข้าไปเพิ่มเอง ก็ยังได้

ที่าำคัญ โคดที่เราเขียนออกมาทั้งหมด เรายังสามารถเอาไป Embed เพื่อแสดงผล ที่ไหนก็ได้อีกด้วย ตามตัวอย่างข้างล่างนี้เลยครับ

 

ลองไปเล่นดูนะครับ สำหรับผม ผมว่ามันมีประโยชน์พอสมควรเลยทีเดียว

]]>
jQueryTips wrote a new story "Titanium Mobile + HTML + Native Scrolling". Tue, 20 Dec 2011 23:55:39 +0700 http://jquerytips.oscool.com/blogs/view/3143 http://jquerytips.oscool.com/blogs/view/3143 jQueryTips jQueryTips มาคุยกันเรื่อง Mobile Dev กันอีกสักรอบ ... ช่วงนี้ผมเห็น App หลายๆตัว เริ่มเปลี่ยนมาใช้ HTML5 กันมากขึ้น ซึ่งก็พอจพมองได้ว่าเป็นข่าวดี เพราะ HTML เป็น เทคโนโลยี ที่ ง่าย แล้วก็ ไปได้ทุก Platform

ก่อนหน้านี้ผมมีปัญหากับการเขียน App ใน Titanium คือมันมีปัญหากับ Table พอ เนื้อหายาวๆ แล้ว Scroll ขึ้นลงเร็วๆ มันจะกระตุก หน่อยๆ ไม่ค่อย นิ่มนวลเท่าที่ควร ก็เลยคิดว่า จะลองเปลี่ยนมาเป็น HTML5 ในส่วนของ Table + JS Scrolling เข้าท่าๆ สักตัว

แต่จนแล้วจนรอด ก็ไม่มีตัวไหนได้อย่างใจผมเลย

จน iOS update มาถึง v5 นี่แหละ ถึงได้รู้ว่า คิดถูกแล้ว

Scrolling ของพวก Mobile มันจะ มี โมเมนตั้ม ที่ต่างจาก การ Scroll ขึ้นลงของ Browser ค่อนข้างมาก เพราะฉะนั้น ถ้าเราเขียน HTML Table ธรรมดา ลงไปเป็น App ความรู้สึกมันจะรู้เลย ว่าไม่ใช่ แต่ วันนี้ Apple แก้ปัญหาให้เราแล้วล่ะครับ

แล้วทั้งหมดก็แก้ปัญหาด้วยคำว่า

overflow:scroll;

-webkit-overflow-scrolling:touch;

 

เท่านั้นเอง จากนั้นผมก็ลอง Lab ด้วยการเอา Titanium มาเป็นโครง แต่ Table ใช้ HTML ดิบๆมา Render แล้วเพิ่ม style พวกนี้ ลงไปใน table เท่านั้นแหละ เนียนกริบ

 

ลองไปอ่านตัวอย่าง แล้วก็วิธีใช้ที่ link ด้านล่างนะครับ ผมขี้เกียจเขียนซ้ำเค้า

http://johanbrook.com/browsers/native-momentum-scrolling-ios-5/

 

บอกได้เลย ถ้าเป็นอย่างนี้ เทรน HTML5 ใน Mobile มาแทน Native ได้แน่ๆ

 

]]>
jQueryTips wrote a new story "HTML to PDF ตัวไหนดี วันนี้ผมมีคำตอบ ...". Tue, 20 Dec 2011 23:45:06 +0700 http://jquerytips.oscool.com/blogs/view/3142 http://jquerytips.oscool.com/blogs/view/3142 jQueryTips jQueryTips สวัสดีครับ หายหน้ากันอีกไปพักใหญ่ๆ แต่ว่าก็ยัง อัพเดทอยู่ใน Fan Page อยู่เรื่อยๆ นะ แต่ว่าถ้าเป็น บทความยาวๆ นี่มันท้อ แฮะ 555

แต่วันนี้ ยังไงก็มาแล้ว ก็จับประเด็น บางเรื่องมาเล่าสู่กันฟัง...

พอดีช่วงนี้ผมกำลัง ทำงานในส่วนออก Report พอดี ซึ่งที่ต้องการก็คือ ออก Report เป็น PDF อันที่จริงมันก็ไม่มีปัญหาอะไรหรอก Lib PDF มีอยู่ถมไป Zend_Pdf ซึ่งทำงานได้ละเอียดมากๆ ก็มีอยู่ แต่ด้วยความขี้เกียจ เลยไม่อยากไป Add Columns ไปสร้างสี แบ่งล๊อกอะไรให้มันวุ่นวาย

แล้วก็จำได้ด้วยว่าเคยเห็น Web ตั้งเยอะที่มัน Convert HTML เป็น PDF มันน่าจะมีใครทำ Lib อะไรมาให้ใช้บ้างน่า สรุปได้ แคนดิเดท มา 3 ตัว ประกอบไปด้วย

1. TCPDF

2. Dompdf

3. mPDF

ก็เลยค่อยๆลอง ไปทีละตัว โดยที่แต่ละตัว ก็มีข้อเด่น ข้อด้อยต่างกันไป ซึ่งแรกเริ่ม ผมก็ไล่มาเลย ตั้งแต่

TCPDF

ตัวนี้ค่อนข้างจะใช้ง่ายมาก ไม่ต้อง Config อะไรวุ่นวาย Font ก็มี ที่ Support ภาษาไทยมาให้ในตัว คือ "Freeserif" ไม่ต้องทำอะไรเท่าไหร่ ตอนแรกก็คิดว่าจะหยุดที่ตัวนี้แหละ แต่พอทำไปทำมาเกิดปัญหา คือมันสามารถอ่าน Stylesheet ได้แค่เล็กน้อยเท่านั้น พวก attrs ง่ายๆ อย่าง  color อะไรแบบนี้

แต่ว่ามันดันอ่านพวก float, padding, margin เพี้ยนๆ ไม่เหมือน HTML ที่ทำมาเท่าไหร่ ซึ่งมันยากมาก เพราะผมต้องทำ HTML เป็น table เกือบทั้งหมด เลยเปลี่ยนๆ ลองตัวใหม่

Dompdf

ตัวนี้ลองอ่าน Document แล้ว ก็ลองใช้งาน ถูกใจมากเลย ถึงจะ config ลำบากไปนิด แต่ว่าใช้งานง่าย โคดเขียนสวย Doc มีตัวอย่างเยอะ แล้วก็ดู ค่อนข้างโปรที่สุด แต่....

พอถึงเรื่องภาษาไทย ผมพยายาม Add Font ไทยเข้าไป มันก็ได้อยู่ ถึงจะลง Font ค่อนข้างลำบากหน่อย แต่พอเอามา Render จริงๆ font ไทย เนียนนะครับ ใช้ได้หมด แต่สระ เสือกกลายเป็น สี่เหลี่ยมหมด (คิดว่าคงมีวิธีแก้ แต่ตอนนี้ไม่ได้หาต่อแล้ว) ก็เลยข้ามไปก่อน กะว่าจะมาหาวิธีแก้ ที่ตัวนี้แหละ แต่ยังไงขอลอง ตัวถัดไปก่อน

mPDF

ตัวนี้บอกตามตรง ตอนแรกผมค่อนข้างจะไม่สนใจ ด้วยความที่หน้าเว็บ ดูไม่โปร (ใช้ WordPress ไม่เปลี่ยน Theme) PageRank ไม่ขึ้นเลย Search หาก็ไม่ค่อยมีข้อมูล

แต่ก็ลองดู เพราะว่า คงใช้เวลาไม่นาน ดูตามตัวอย่างแล้ว เขียนตามนิดเดียวก็คงรู้ผล

แต่เรื่องไม่น่าเชื่อก็เกิดขึ้น คือ Lib ตัวนี้กับทำตามที่ผมต้องการได้ทุกอย่าง คือโจทย์ของผมมีว่า

- ต้องสามารถอ่าน CSS ได้

- ต้องสามารถแสดงผล ได้เหมือน HTML เพี้ยนได้ไม่เกิน 2%

- ต้องสามารถใช้งานกับภาษาไทยได้ 100%

- ใช้ง่ายไม่ต้องต่อ online กับ Service ภายนอกตัวอื่นๆ

- ต้องสามารถ ทำ Paging ในตัว PDF ได้

- ต้อง Config header + footer ได้

- ต้องอ่าน img แล้วนำเข้าไปได้

ไม่น่าเชื่อก็ต้องเชื่อแหละครับ Lib ตัวนี้ทำได้หมดเลย ได้มากกว่าที่ผมต้องการเสียอีก แถมระบบการ Config ก็เอื้อ แก้การประยุกต์ใช้งานมากๆ

มาลองดูตัวอย่างที่ผมทำการ Lab ไปนะครับ

สมมุติว่า ผมมี HTML ตามนี้

<?php

$html = <<<EOF
	<div id="wrapper">
		<div class="row">
			<div class="picture"><img src="http://a2.twimg.com/profile_images/1699637550/iannnnnAVATAR_normal.png" /></div>
			<div class="content">
				<div class="header">
					<a href="#">Name<span>@username</span></a>
					<small>4m</span>
				</div>
				<p lang="th">[THAI TEXT TO SHOW]</p>
				<div class="footer">Footer text</div>
			</div>
		</div>
		<div class="clear"></div>
	</div>
EOF;

?>

 

แล้วผมมี stylesheet ประมาณนี้

.row { background:url(http://www.domain.com/assets/images/bg.jpg); }
.row { clear:both; width:500px; padding:10px; border-radius:5px; font-family:naipol; font-size:11px; background-color:#EEE; }
.picture { float:left; display:block; width:48px; height:48px; }
.picture img { width:48px; height:48px; border-radius:5px; }

.content { margin-left:60px; }
.content .header small { float:right; text-align:right; }
.content p { margin:0; padding: 5px 0; }
.content .footer { color:orange; }

.clear { clear:both; }

 

ผมลองเขียนโคดขึ้นมาเพื่อ Gen ออกมาดู

<?php
$mpdf = new mPDF();
//$mpdf->setDisplayMode('fullpage');
//$mpdf->setAutoFont();

$mpdf->writeHTML($style, 1);
$mpdf->writeHTML($html);
$mpdf->Output();

?>

โดยที่ Stylesheet ผมใส่ไว้ในตัวแปล $style นะครับ

 

ผลลัพธ์ที่ออกมาของผม มาตามรูปข้างล่างนี้ครับ

ซึ่งเหมือนกับ HTML เป๊ะเลย เรื่องของ Font Thai ผมใช้ "Thonburi" เป็นตัว font ครับ

ที่สำคัญ Lib ตัวนี้ยังมีการ config font ที่ฉลาดมา และยังสามารถ Detect ภาษาให้เองได้ด้วยอีก

http://mpdf1.com/manual/index.php?tid=453

 

ลองไปเล่นดูนะครับ มันเหมาะกับการ Generate Reports, Coupons หรือ หน้าเว็บ มาก

 

]]>
jQueryTips wrote a new story "ทำความรู้จักกับ JavaScript Pattern ในเชิงลึก". Tue, 29 Nov 2011 23:27:34 +0700 http://jquerytips.oscool.com/blogs/view/3046 http://jquerytips.oscool.com/blogs/view/3046 jQueryTips jQueryTips วันนี้ผมเอาลิ้งก์แนะนำ การเขียน JavaScript ตาม Pattern แบบต่างๆ มาแนะนำ ซึ่งค่อยข้างแปลกสักหน่อย คือผมมา อัพบล็อกแต่ไม่อยากเอา บทความเค้ามาแปล เพราะว่า กลัวจะแปลไม่ถูก 555

แต่ว่า บทความนี้มันดีจริงๆ ผมเลยต้องเอามา บล็อกกัน ทั้งๆ ที่ Copy มาเป็นลิ้งก์แบบนี้แหละ

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

เพราะ JS ในปัจจุบันมัน ค่อยข้างจะแทรกซึมไปทุกที่ ทั้ง HTML5, Mobile Framework, API Protocol, Push Engine แล้วก็อีกล้านแปด ในอนาคตนี้ก็ไม่มีทางตายง่ายๆ นับวันมีแต่จะใหญ่โตขึ้นเรื่อยๆ

ก็ลองๆดูๆ กันหน่อยนะ วันนี้ขออัพเดท แบบคนขี้เกียจสักหน่อย 555

ลองไปดูตามลิ้งก์นี้ครับ เขียนดีมากๆ

http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth

 

 

 ]]>
jQueryTips wrote a new story "ผมบอกคุณแล้ว .... คนโง่ก็ Code ได้". Thu, 17 Nov 2011 02:07:50 +0700 http://jquerytips.oscool.com/blogs/view/3012 http://jquerytips.oscool.com/blogs/view/3012 jQueryTips jQueryTips ที่ท่านกำลังจะอ่านต่อไปนี้ เป็นเรื่องจริง ของตัวผมเอง ที่ไม่เคยตีพิมพ์ที่ไหนมาก่อน 5555

"เขียนโปรแกรมเหรอ" ?

ตัวผมก็ไม่ได้เรียนเกี่ยวกับทางด้านนี้มาเลยนะ ไม่เคยคิดด้วยซ้ำ จบโฆษณามาล่ะ เพราะตอนเรียนมหาลัย ไม่ชอบเลข กับ ภาษาอังกฤษ ถึงขนาดเคยติด F ซะด้วยซ้ำ แถมจบช้ากว่า คนอื่นปีนึง เพราะว่าติดสาว 555

จบมาก็ไม่รู้จะทำอาชีพอะไร เพราะว่าโง่มาก ดีที่ตอนนั้นเห็นเว็บมันกำลังมา หันไปทางไหนมีแต่ คนเล่นเน็ท เลยหันมาศึกษา เพราะอยากรวยอย่างเดียว คิดว่า ทำเว็บเสร็จ สงสัยคนจะมาลงโฆษณาเยอะ (เคยเห็นค่าโฆษณาบางเว็บแล้วมันเยอะดี) ลงสัก 10 ป้าย ป้ายละพัน ได้สักเดือนละ 10,000 นึง โอ้ย แหล่ม มีตังค์เที่ยวแน่กู !!!

ก็เลยหัดเขียนเว็บแม่งเลยนี่ เดี๋ยวทำเว็บดังๆ รวยไม่รู้เรื่อง ฮ่า ฮ่า ฮ่า

ในใจตอนนั้นคิดว่า มันจะไปยากอาไร้ เดี๋ยวไปซื้อหนังซื้อสอนทำเว็บ ที่ร้านหนังสือ ดอกหญ้า มาสักเล่ม อ่านจบกูก็ทำได้แล้ว สุดท้ายได้ หนังสือ Dreamweaver มาเล่มนึง จำไม่ได้ว่า เวอร์ชั่นอะไร คลับคล้าย คลับคลาว่าเป็น 5 หรือ 6 นี่ล่ะ มั้ง (จนเดี๋ยวนี้เปิดไปได้ไม่เกิน 30 หน้า)

สุดท้ายมาลองทำ เอาภาพมาปะๆ ติดๆ แล้วก็ลองทำ เหมือนเว็บ Idol ดู แต่ทำไมทำแบบมันไม่ได้วะ แถมเครื่องมือเม่งก็โครตจะเยอะ ใครมันจะไปใช้เป็น -*-

เลยมานั่งตรึกตรองดู สงสัยเพราะว่าเราไม่มีพื้นฐาน ไม่มีคนสอน อืมม์ น่าจะใช่ละ....

ตัดสินใจได้ปุ๊บ ไปสมัครเลย คอร์สทำเว็บ หวานกูแล้วๆ ทีนี้ได้แน่ ได้แน่ๆ หึ หึ หึ

วันแรกไปนั่งเรียน จำได้ว่า อ. เอา โปรแกรมอะไรไม่รู้ของ Adobe มาสอน เป็นโปรแกรมทำเว็บ แบบนึงคล้ายๆ Dreamweaver นี่ล่ะ จำชื่อไม่ได้ เรียนๆ ไป อู้ยยยย ง่าย เดี๋ยวอีก 4-5 ครั้งจบคอร์ส เสร็จกูแน่ เว็บ Idol ลอกแม่งเลย ฮ่า ฮ่า อ่า พอมาถึงครั้งที่สี่ เริ่มชักไม่แน่ใจ

"ทำไมบทเรียนกู มันมีแต่เอาภาพมาป่ะๆ ติดๆ วะ นี่มันต้องมีอะไรผิดพลาดแน่ๆ" เลยตัดสินใจไปถาม อ. ว่าเนี่ยๆ เว็บ Idol มันทำแบบนี้ๆ เมื่อไหร่ อ จะสอนสักที แบบว่า ใจร้อนๆ อยากรวย

อ. อมยิ้ม ตอบมาด้วยสีหน้า สมเพชเต็มที บอกว่า "นี่คุณ เว็บแบบนี้มันต้องเขียนโปรแกรมด้วย ที่คุณเรียนเค้าเรียก เว็บดีไซด์" !!!!!!!

เหมือนฟ้าผ่ากลางวัน "เปรี้ยง" ความฝันในวัยหนุ่ม กระเจิงทันที

แล้วนี่..... ไอ้โปรแกรมที่กูใช้อยู่มันไม่ใช่การเขียนโปรแกรมหรอกเหรอ ???

อ้อ เราเป็นแค้ผู้ใช้โปรแกรมสินะ เราเป็นแค่ ผู้ใช้ ผู้ใช้ ผู้ใช้ Y_Y

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

ตัดสินใจได้อีกปั๊บ ก็เอาอีก ไปสมัครอีก คอร์ส PHP Language
(ขอบคุณการตัดสินใจวันนั้นของตัวเองมากๆ)

แล้วก็ได้มาเทคคอร์สสั้นๆ เกี่ยวกับ PHP รวมถึง Database นิดหน่อย ตอนไปเรียน ยอมรับเลยว่า เราคงจะโง่ที่สุดในห้อง 555

เพราะว่าพิมพ์ดีด ยังไม่ได้เล้ย ต้องคอยให้ พี่ข้างๆ Copy Code ให้เพราะพิมพ์ไม่ทันเค้า อายสาดดดดด

พอไปได้สัก 2-3 ครั้ง ท้อครับ เพราะแม่งไม่เข้าใจเลย if if else else อะไรวะ งงชิบ แล้ว แถมยังขาดเรียนไปหนึ่งครั้งเรื่องสำคัญ จำได้ว่าเป็นเรื่อง เก็บ Login ใน Cookie (ก่อนหน้านั้นเรียนเรื่อง session) แต่ก็อดทนเรียนจนจบ ทั้งๆที่ใจมันถอดไปแล้วด้วยซ้ำ แต่เสียดายตังค์ ค่าเรียน

ก่อนจบคอร์ส จำได้ว่า อ ให้การบ้านมา ให้ทำ Web Application แบบมีการตอบโต้กันได้ มี Database มี การใช้ Text เก็บข้อมูล (Flat Data) ซึ่งก็ไม่ได้สนใจอะไรมากนัก เพราะใจมันถอดทิ้งไปแล้ว
ความเชื่อที่จะที่แบบ เว็บ Idol ไม่มีหลงเหลือ

โอ้ ความฝันในวัยหน่ม มันช่างสั้นนัก …. T_T

จบแล้วครับ …. The End


เอ้ย ยังๆ มันต้องเหมือน เถ้าแก่น้อยดิ มันต้อง Happy Ending 555

หลังจากจบมา ผมก็ลองเอา โคดที่ พี่ใจดีคนนั้น อุตส่าห์ Copy มาให้ (ผมจำชื่อพี่ไม่ได้ แต่ก็ต้องขอ ขอบคุณมากครับ ใจพี่หล่อมากครับ) มานั่งอ่านดูทีละบทๆ จริงๆ แล้วถ้ามาตอนนี้ หลายๆ คนคงด่าผมว่าโง่ โคดมันง่ายๆ เองมีประมาณ
- วิธีใช้งาน Cookie
- วิธีใช้งาน Session
- แบบฝึกหัดท้ายบท ทำระบบ Member Login
- วิธีการติดต่อ Database
- วิธีการเก็บข้อมูลลงไฟล์
- แบบฝึกหัด ทำระบบ Guest Book

แล้วก็อื่นๆ ประมาณนี้แหละ ไม่หนีกัน

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

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

ภูมิใจมากกกกกกกกก

และตั้งแต่วันนั้น ผมก็ยึดอาชีพนี้มาได้ 8 ปีแล้วครับ

เรื่องทุกเรื่องที่ผมเขียนใน Blog แห่งนี้ คือสิ่งที่ผมศึกษาเอาเองทั้งหมด จากคนที่ติด F วิชา Eng จนตอนนี้อ่าน Doc Eng คล่องเลยครับ

เอาล่ะ พอๆ เดี๋ยวจะหาว่า ขี้คุย 555


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

]]>
jQueryTips wrote a new story "วันนี้ มาออกแบบ Web Service ด้วย PHP กันเถอะ (CodeIgniter Version)". Sat, 12 Nov 2011 01:41:33 +0700 http://jquerytips.oscool.com/blogs/view/2991 http://jquerytips.oscool.com/blogs/view/2991 jQueryTips jQueryTips โอ้โห ไม่ได้อัพเดทบล็อกนี้ (มีบล็อกเดียว) มานานมากๆ เผลอแป๊บเดียว 4 เดือนเข้าไปแล้ว ก็มันขี้เกียจนี่หว่า ไว้จะทำ Screen Cast แทนไม่รู้จะลำบากขึ้นมั้ย 555

เอาล่ะ ไหนๆ ก็อัพ แล้ว เอาเรื่องที่หาอ่าน บทความภาษาไทย ไม่ค่อยได้ดีกว่า เรื่องของ "Web Service"  ครับ ปกติส่วนมากจะมีแต่บทความวิธีใช้ แต่ว่า วันนี้ผมจะมาเขียน บทความ "วิธีทำ" กันดีกว่า

สมัยนี้ หนียังไงก็หนีไม่พ้น กับการต้องเข้าไปยุ่งกับ API ของเว็บบิ๊กๆ ทั้งหลาย ซึ่งแต่ละเว็บก็มีการใช้ Protocol ต่างกันไป ถ้ายิ่ง บิ๊กมาก ก็จะมี Protocol ให้ใช้แทบจะครบ

มีทั้ง RESTful, XML-RPC, JSON-RPC, SOAP, etc. ซึ่งลงท้ายทุกตัวทำงานเหมือนกันหมด คือใช้ติดต่อ ระหว่าง โปรแกรม ซึ่งตอนนี้ API ของเว็บทุกเว็บ อย่างน้อยจะต้องมี  1 protocol คือ REST เพราะว่ามันง่ายกับ Developer ในการติดต่อ แล้วก็เขียนเชื่อมไป จะว่า XML-RPC, JSON-RPC ก็ต้องถือว่า เป็น REST ด้วยเหมือนกันแหละ เพียงแต่ Response Format ต่างออกไป

เอาล่ะ ทฤษฎีอาจจะไม่ค่อยแน่น แต่ปฎิบัติ ผมพอไหว  555

วันนี้เราจะมาออกแบบ ชุด API ของ REST กัน โดยที่โจทย์ของเรามีดังนี้

1. API จะต้อง Authen จากโปรแกรมเชื่อมใช้งานได้

2. Structure ต้องเป็นระเบียบสามารถเพิ่ม ชุด function ได้ง่าย

3. Response ต้องออกได้ทั้ง XML และ JSON

4. ต้องมี Failed Message  ในกรณีที่ API ไม่สามารถทำงานได้สมบูรณ์

อุปกรณ์เครื่องครัวที่ต้องเตรียมมา

1. CodeIgniter ตัวนี้ใช้เป็น Base Render MVC เฉยๆ จะมีไม่มีก็ไม่ว่ากัน เอา Structure ตามถนัด

2. Zend_Rest_Server ตัวนี้ก็เหมือน เนื้อสัน ไม่มีก็ทำ เสต๊ก ไม่ได้

3. Zend_Json ตัวนี้เอาไปแปลง Response Format  กลับไป กลับมาระหว่า XML -> JSON

เอาล่ะ มาเริ่มกันเลย....

ก่อนอื่นเราต้องมี File Bootstrap ของ API คือตัวกลางนั่นแหละ เวลาที่ ใครเรียกจะต้องมาที่ไฟล์นี้ก่อนซึ่งตัวนี้ผมใช้ Controller นั้น CI  มาทำ

โดยในไฟล์นี้ผมตั้งชื่อ Controller ว่า Rest.php

 

<?php

class Rest extends CI_Controller {

	public static $server;
	
	private $_methods = array('blogs');
	
	public function __construct()
	{
		parent::__construct();
		
		// load zend reset server class

		
		require_once('Zend/Rest/Server.php');
		self::$server = new Zend_Rest_Server();
		
	}
	
	public function _remap($method, $attrs)
	{
		// check existing api methods
		if (!in_array($method, $this->_methods)) {
			die('API is not exists');
		}
		
		// if having specific method
		if (method_exists($this, $method)) {
			call_user_func_array(array($this, $method), $attrs);
		}
		else {		
			$call = "service_{$method}";
			$this->load->model('services/'.$call);
			self::$server->setClass($call);
		}
		
		// keep response
		self::$server->returnResponse(true);
		$xmlstr = self::$server->handle();
				
		// response format
		$format = $this->input->get_post('format');
		if (strcasecmp($format, 'json') == 0)
		{	
			// format output to valid structure
			$dom = new DOMDocument('1.0');
			$dom->preserveWhiteSpace = false;
			$dom->formatOutput = true;
			$dom->loadXML($xmlstr);
			
			// now we have valid format
			$xmlstr = $dom->saveXML();
				
			// zend not provide attribute, so we change to the code below
			$this->load->loadClass('Zend_Json');
			$response = Zend_Json::fromXml($xmlstr, true);		
			
			header('Content-Type:application/javascript;charset=' . config_item('charset'));
			echo Zend_Json::prettyPrint($response); exit(0);
		}
		
		// return XML format
		header('Content-Type:text/xml; charset='.config_item('charset'));
		echo $xmlstr;
	}
		
}

?>

 

ไฟล์นี้ก็มีประมาณนี้ครับ โดยแต่ละ method มีการทำงาน คร่าวๆ ดังนี้

method __construct

ส่วนนี้จะเป็นส่วนของการ include Zend_Rest_Server เข้ามาใช้งาน กับโหลด helper บางตัวเข้ามา (ผมจะขยายงาน helper ตัวนี้ทีหลัง)

method _remap

ส่วนนี้เป็น คล้ายๆ magic method ใน CI คือ เอาง่ายๆ มันเหมือน __call ใน class ปกติ ที่เวลาเราเรียก method อะไรมันจะเข้ามาที่นี่ก่อน นั่นแหละ

ส่วนการทำงานของมันก็คือ เป็นตัวรับ method ที่ user เข้ามาใช้งาน จุดสำคัญช่วงแรกอยู่ที่โคดตรงช่วงนี้

 

$call = "service_{$method}";
$this->load->model('services/'.$call);
self::$server->setClass($call);

 

จะเป็นตัวรับ method ว่า user call อะไรมาเช่น  blogs, albums, friends

ก็จะไปเรียก model ที่อยู่ตาม path แบบนี้

/application/models/services/service_blogs.php

จากนั้นก็เอา methods ใน service_blogs ว่ามองเป็น method ของชุด API blogs

ส่วนท้ายๆ มันคือกันทำ  format ระหว่าง xml, json ค่อยๆ ไล่โคดเอาแล้วกันนะครับ 

 

ทีนี้มาดูในส่วนของ service_blogs.php  กันว่า เรามีอะไรบ้าง

 

<?php

class service_blogs extends CI_Model {

	public function __construct()
	{
		parent::__construct();
	}
	
	public function GetItems($page=1, $limit=20, $sort="created_at-desc", $criteria=array())
	{
		// implement
		
		return array();
	}
	
	public function GetItem($id)
	{
		// implement
		
		return array();
	}
	
}

?>

 

เราจะมี methods ที่รอการ implement เรียงอยู่ครับ ซึ่งถ้าเราทำ สองไฟล์นี้จบแล้ว เราจะสามารถเรียกแบบนี้ได้

http://xxx.com/api/rest/blogs?method=GetItem&page=1&limit=20

โดยถ้าเราแยกชิ้นของ URL ออกมาจะมองเป็น โปรแกรมได้ดังนี้

1. rest = controller (CI)

2. blogs = model (models/services/service_blogs.php)

3. method:GetItems = method นึง ใน class ของ service_blogs

4. &page=1&limit=20 = arguments ของ method นั้นๆ

ที่เหลือ เราก็แค่ implement ลงไป Zend_Rest_Server จะจัดการทำ ให้ออกมาเป็น XML เอง

 

ทีนี้เราลองมา Implement ดูสักนิด ที่ method GetItem แล้วกัน สมมุตผมโคดลงไปแบบนี้

 

public function GetItem($id)
	{
		return array(
			'response' => array(
				'id' => $id,
				'message' => "You are calling blogs:GetItem with parameter id = ".$id
			)
		);
	}

 

แล้วผมมาลองเรียกแบบนี้

http://xxx.com/api/rest/blogs?method=GetItem

สิ่งที่ผมจะได้กลับมาก็คือ

เพราะว่าอะไรครับ ?

เพราะว่า id ผมเป็น field บังคับ Zend_Rest_Server จะมาเป็นตัวจัดการตรงนี้เอง แต่ถ้าผมเขียนโคดใหม่เป็น

 

public function GetItem($id=123)
	{
		return array(
			'response' => array(
				'id' => $id,
				'message' => "You are calling blogs:GetItem with parameter id = ".$id
			)
		);
	}

 

สังเกตุตรง id=123  นะครับ

ผลลัพธ์ที่ได้ ก็จะผิดกัน จะเหมือนกับผมเรียกไปด้วย URL

http://xxx.com/api/rest/blogs?method=GetItem&id=123 นั่นแหละครับ ตามภาพด้านล่าง

 

 

เอาล่ะ ทีนี้เราลองมาทำการ validate ชุดของ api แบบง่ายๆกันดูนะครับ ผมจะเพิ่มโคดอีกหน่อย ดังนี้

 

public function GetItem($id=123)
	{
	 	$username = $this->input->get_post('username');
	 	$password = $this->input->get_post('password');
	 	
	 	if (strcmp($username, 'Teepluss') != 0 || strcmp($password, '123') != 0) {
	 		throw new Exception('Sorry, User is exists our database.');
	 	}
	 	
	 	
		return array(
			'response' => array(
				'id' => $id,
				'message' => "You are calling blogs:GetItem with parameter id = ".$id
			)
		);
	}

 

จะเห็นได้ว่า ผมมีการร้องขอ ให้กรอก  username + password เข้ามาแล้ว ที่ผมไม่เอาใส่เป็น parameters ของ method เพราะจะทำให้ดูว่ามันจะเรียกแบบนี้เลยก็ได้ ส่วนค่าตรง parameters ของ method จะแทนได้ทั้ง  get และ post เลยเช่นเดียวกัน แตกต่างกันตรงที่ parameter Zend Rest มีการจัดการ validate เรื่อง missing parameter ให้ด้วย เท่านั้นเอง

 

ทีนี้ผมจะลองเรียกไปใหม่ แบบนี้

http://xxx.com/api/rest/blogs?method=GetItem&id=123

ข้อความตอบกลับมาของผมก็คือ

 

นั่นก็เพราะผมยังไม่ได้ใส่ username + password ไปนั่นเอง เอาใหม่ทีนี้ใส่ให้ถูกๆ เป็น

http://xxx.com/api/rest/blogs?method=GetItem&id=123&username=Teepluss&password=123

ข้อความตอบกลับของผมก็จะเป็น

 

ถูกต้องตามปกติ และนอกจากนั้นแล้ว จากโคด ที่เราทำการเขียนไว้ต้องแต่ controller rest.php ยังสามารถทำให้เราจัดการกับ format ได้อีกด้วย เช่นผมพิมพ์ไปว่า

http://xxx.com/api/rest/blogs?method=GetItem&id=123&username=Teepluss&password=123&format=json

ค่าที่ตอบกลับมาผมจะได้มาใน format ของ  json ดังภาพด้านล่าง

 

ซึ่ง Format JSON นี่ล่ะ เหมาะนักในการไปใช้ใน โปรแกรมจาก อุปกรณ์ต่างๆ เช่น iPhone, Android เป็นต้น

 

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

เจอกันโอกาสหน้านะครับ

Tee++;

]]>
jQueryTips uploaded a new video "Appcelerator Titanium Mobile 1.3 launching video player from WebView in Android".
Appcelerator's Titanium Mobile SDK version 1.3 will be the first version of Titanium that is capable of launching the built-in video player from WebView controls in Android. This video shows an example of this inside the Android emulator. The small test a…
]]>
Sun, 21 Aug 2011 11:43:15 +0700 http://jquerytips.oscool.com/videos/view/759 http://jquerytips.oscool.com/videos/view/759 jQueryTips jQueryTips
Appcelerator's Titanium Mobile SDK version 1.3 will be the first version of Titanium that is capable of launching the built-in video player from WebView controls in Android. This video shows an example of this inside the Android emulator. The small test application was written in Titanium.
]]>
jQueryTips wrote a new story "Facebook oAuth แบบเบาๆ". Mon, 08 Aug 2011 23:28:40 +0700 http://jquerytips.oscool.com/blogs/view/2539 http://jquerytips.oscool.com/blogs/view/2539 jQueryTips jQueryTips เบื่อเรื่อง mobile กันรึยังครับ จริงๆ ตอนแรกว่าจะเขียนเรื่อง Table ของ Ti  ต่อเลย แต่คิดว่า มันต้องลำดับความคิดเยอะเกินไป วันนี้อยากเขียนอะไรเบาๆ ที่ใช้เวลาไม่เกิน 20 นาที เลยเอาเรื่อง Facebook ง่ายๆ มาคั่นเวลาไปก่อนละกัน

จริงๆ แล้วการทำ oAuth ของ Facebook เพื่อ Request Access Token นั้น ตัว SDK มันก็ทำงานได้ค่อนข้างดีแล้ว แต่ว่า บางทีก็ขี้เกียจ implement วุ่นวายแบบนั้น เลยเขียนลวกๆ ง่ายๆ ออกมา ลองมาดูขั้นตอนกัน ง่ายมากๆ

 

$app_id = "APP_ID";
$app_secret = "APP_SECRET";
$callback_url = "http://www.callbackdomain.com";

$code = @$_GET['code'];
if ($code)
{	
	$params = array(
		'client_id' => $app_id,
		'redirect_uri' => $callback_url,
		'client_secret' => $app_secret,
		'code' => $code
	);
	$url = "https://graph.facebook.com/oauth/access_token?" . http_build_query($params); 
	$result = file_get_contents($url);
	
	parse_str($result, $output);			
	echo $output['access_token'];
}
else
{				
	$params = array(
		'client_id' => $app_id,
		'scope' => "publish_stream,offline_access",
		'redirect_uri' => $callback_url,
		'display' => "wap"
	);
	
	$url = "https://graph.facebook.com/oauth/authorize?" . http_build_query($params);
	echo "<script>window.location='" . $url . "';</script>";
}

 

 

แค่นี้ล่ะ อิอิ จบละ ไปนอนละ 555

]]>
jQueryTips wrote a new story "[Part 2] Titanium Mobile Starting with app.js". Sun, 24 Jul 2011 22:05:52 +0700 http://jquerytips.oscool.com/blogs/view/2484 http://jquerytips.oscool.com/blogs/view/2484 jQueryTips jQueryTips สวัสดีครับ ภาค 2 มาซะทีนะครับ อิอิ

จริงๆ แล้วผมมีเรื่องอีกหลายเรื่องที่อยากจะมาเขียนทั้ง Yahoo Query Language (YQL) หรือว่าจะเป็น Zend JSON-RPC Server รวมไปถึง jQuery MVC แต่ก็อดใจไว้ เพราะกลัวว่าเรื่อง Titanium จะไม่จบแล้วก็ขาดความต่อเนื่อง ซึ่งผมกะๆ เอาโดยประมาณกว่าจะเขียนจนจบ คงมีเยอะแน่ๆ แล้วดูจากการ update ที่บ่อยมากๆ ของผม คงจะเขียนสัก ปี สอง ปีเป็นแน่แท้ 555

แต่เอาเถอะครับ ต่อจากนี้จะพยายามมาอัพเดทให้บ่อยขึ้นละกัน

วันนี้ก่อนที่เราจะมาลงมือเขียนจริๆ ผมอยากจะเล่าให้ฟังถึง โครงสร้างของ Titanium Mobile สักนิดนึง อย่าเพิ่งเบื่อกันไปก่อนนะครับ

เริ่มต้นตั้งแต่เรา Create Project ขึ้นมาใหม่ เราจะพบไฟล์ตามภาพด้านล่างนี้

โดยจะประกอบไปด้วย ไฟล์ Config, License, Readme แล้ว ก็ โฟลเดอร์ที่เราไว้ใช้ทำงาน คือ Resources

แล้วถ้าเราแตก Resources ออกมาดู (ตามภาพด้านล่าง) จะพบว่ามี ไฟล์ app.js นั่นล่ะครับ คือไฟล์แรกที่เราจะใช้ในการเขียน App ส่วนโฟลเดอร์ iphone, android คือที่ไว้เก็บไฟล์ ภาพเวลารัน App ขึ้นมาหรือไฟล์ที่เกี่ยวข้องกับ app โดยตรงเช่น icon app อะไรแบบนั้น

ถ้าเราจะทำให้ App รองรับ Retina Display สำหรับ iPhone เราจะใส่ @2x ตามเข้าไปด้วยสำหรับทุกๆ ไฟล์ image

ทีนี้มาดูกันที่ไฟล์  app.js อีกที

เมื่อเรา Create Mobile Project ขึ้นมา Ti Studio ก็จะสร้าง App มาให้เราเลย พร้อมกับ TabGroup ซึ่งจริงๆ แล้วเราจะเริ่มต้น Application  ด้วยอะไรก็ได้ เช่น

Windows, TabGroup, Navgroup

ซึ่งถ้าจะพูดกันตรงๆ ไอ้ TabGroup นี่แหละง่ายสุด แต่ถ้าจะให้ Performance ดีที่สุด ผมว่าเริ่มด้วย Window ปล่าวๆ ยังไงมันก็ต้องดีกว่า แต่ช่างมันเหอะ ไม่ใช่เว็บนี่ ต้องมาคำนึงอะไรกันมากเล่า 555

ทีนี้มาลองดูโคดของ app.js กันไปทีละส่วน

ช่วงบรรทัดที่ 1-20

ช่วงนี้จะเป็นการสร้าง TabGroup ขึ้นมา พร้อมทั้งสร้าง window จากนั้น ก็สร้าง tab ย่อย เพื่อจับ window ลงไปหา tab ย่อยที่ 1 ซึ่งถ้าเราลอง Build ดู ใน Simulator จะแสดงผลตาม ภาพด้านล่าง

ซึ่งส่วนที่เราสร้างก็คือ Tab ด้านล่างที่เขียนว่า "Tab 1" นั่นเอง ส่วนภาพของ Tab ก็คือไฟล์ "KS_nav_views.png" ที่ิอยู่ใน Resources

แล้วก็ผมบอกไปแล้วนะครับ ถ้าเราจะทำ ให้มันรองรับ Retina Display เราจะต้องสร้างไฟล์ @2x ใส่เข้าไปเอง ถ้าตามกรณีนี้ เราก็ต้องมี KS_nav_views@2x.png ประกอบเข้าไปด้วย ส่วนการเลิกไฟล์ ผมเข้าใจว่า App จะเป็นตัวจัดการเอง

ส่วนคำว่า "I am Window 1" นั้น เราจะเห็นในโคด ต่อจาก บรรทัดที่ 20 ตามนี้ครับ

ซึ่งจะเป็นการสร้าง Label ที่มี Text จากนั้นจับยัดลง Window ด้วยคำสั่ง .add()

ต่อมา โดด บรรทัดที่ 31-52 เป็นแค่การ สร้างเข้าไป อีก tab นึงเท่านั้นเอง ตรงนี้ผมขอข้ามนะครับ

ต่อมาดูภาพด้านล่าง

โคดตั้งแต่ 56-64 จะเป็นการ เอา tab ที่เราสร้าง ยัดลง tabgroup ใหญ่ จากนั้นก็สั่งมัน เปิด ซะ เท่านี้เราก็จะได้ ตัวตั้งต้นของ application แล้วครับ ง่ายมากๆ

 

ถ้ามาลองสังเกตุดูการออกแบบ จะเปนในลักษณะ Layer คือ มันจะซ้อนกันเป็นชั้นๆ ไป ตามนี้

label <- window <- tab <- tabgroup

มันจะเป็นชั้นๆ ไป ค่อยๆ add เข้าหากัน หลักการออกแบบนี้เราจะใช้ในทุกส่วนของการเขียน Titanium Mobile ครับ

ซึ่งจริงๆ แล้วตัว Structure หลักมันจะมีอีก หลายส่วนที่อยากให้ลองดูกัน

ไม่ว่าจะเป็น Internation App ด้วย

Internationalization and Localization (i18N)

หรือว่าจะเป็นส่วน Global UI ด้วย .jss 

อันนี้มันอธิบายยากไปหน่อย ยังไงถ้าอยากรู้ลองดูที่ link นี้นะครับ

http://developer.appcelerator.com/blog/2010/08/dealing-with-multiple-screens-and-multiple-languages.html

แล้วก็เนื่องจาก Titanium Mobile มัน Base ด้วย JS ดังนั้นเราจะเขียนไปในทิศทางไหนก็ได้ อาทิเช่น

1. เขียนโดยแต่ออก ด้วย url

คือเขียน 1 view 1 logic ต่อ 1 ไฟล์ อันนี้มันจะเหมือนตัวอย่างที่เค้าให้มาคือ Kitchensink

2. เขียนแบบ OOP โดยมองทุกอย่างเป็นกลุ่มวัตถุ แล้วก็สามารถ Reuse ได้ในส่วนต่างๆ

http://wiki.appcelerator.org/display/guides/Building+Reusable+Factories

3. จะเขียนเป็น MV, MVC, MC อะไรก็ได้ตามแต่ที่จะคิด แล้วก็มองว่าเหมาะกับตัวเอง ทำให้ทำงานง่าย

http://stackoverflow.com/questions/2573592/how-to-organize-js-files-in-a-appcelerator-titanium-project/2594227#2594227

 

ส่วนตัวผมเอง (ตอนนี้) เลิกวิธีการเขียนแบบตัวอย่าง Tweetanium เพราะว่า มันจัดการไฟล์ js ได้เป็นสัดส่วนดี แต่ว่าถ้ามือใหม่ ผมคิดว่าข้อ 1 มันก็ไม่เลวร้ายนะครับ แถมได้ performance ค่อยข้างดีด้วย (คิดเอาเอง) เพราะว่า Process มันแยกกันเป็นชิ้นๆ

ยังไงก็ลองเล่นดูนะครับ

]]>
jQueryTips wrote a new story "[Part 1] ทำความรู้จักกับ Titanuim Platform". Mon, 11 Jul 2011 00:50:43 +0700 http://jquerytips.oscool.com/blogs/view/2422 http://jquerytips.oscool.com/blogs/view/2422 jQueryTips jQueryTips

เอาล่ะครับ มาเข้าสู่โลกของ Mobile กันอีกครั้ง 555

วันนี้ผมจะมาเข้าเรื่องของ Titanium Mobile แล้วนะครับ โดยก่อนที่จะลงมือเขียนกันนั้น มาทำความรุ้จักคร่าวๆ กันก่อนว่า ไอ้เจ้า "Titanium Platform" เนี่ยมันคืออะไรกัน ?

Titanium เนี่ยเป็นเครื่องหมายการค้าของ Appcelerator, Inc. โดยมี Tool ที่เป็นจุดขายเลย คือเครื่องมือพัฒนา Software แบบ Cross-Platform และที่สำคัญคือเป็น Native App ด้วย

คำว่า Native App ก็หมายความ App ที่ออกมา จะมีลักษณะ เหมือนกับ App ที่พัฒนาด้วยภาษาต้นแบบเลย ประมาณนั้น โดยภาษาที่เขียนไม่จำเป็นต้องเป็นภาษา ที่ทาง Hardware แต่ละตัวกำหนด โดยที่ ตัว SDK ของ Titanium จะทำหน้าที่เป็นตัวกลางระหว่าง ภาษาที่เราเขียน กับ ภาษาที่ใช้งานจริงๆ ให้เราเอง พูดง่ายๆ ก็ลองนึกภาพ  API ละกัน แนวๆ นั้นแหละ

อ้าวแล้วทำไมเราต้องมาใช้  Titanium ล่ะ ?

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

1. ภาษาที่ใช้ส่วนมากเป็น Web Skill ซึ่งผมคิดว่า เราๆท่านๆ ก็คงมีติดตัวกันมาพอสมควร จึงไม่เสียเวลามากนัก ในการเรียนรู้

2. ทำที่เดียวมันออกมาได้หลาย Platform อาทิเช่น เขียน Software บน  Windows ได้ของ Mac, Linux แถมมาด้วย หรือว่า เขียน iOS ได้ Android ติดมือมาอีก (อาจจะมีแก้คำสั่งส่วน UI บ้าง)

3. มี Developer ใช้อยู่เยอะ พอสมควร App ใหญ่ๆ บางตัวก็ใช้ อาทิเช่น Ebay ทำให้มีความมั่นใจได้พอสมควรว่า จะไม่ถูกลอยแพ หรือว่า ตัดออกจาก สาระบบ ง่ายๆ

4. ฟรี ไม่ต้องเสียตังค์เพิ่มเติม แต่ถ้าอยากจ่ายคุณ ก็อาจจะได้  IDE ดีขึ้น Module API มากขึ้น ได้เข้าไปดูในส่วน Knowlegde Center มากขึ้น ราวๆ นี้

5. API ทำมาได้ล้อกับ Native Apps อย่าง  ได้ใกล้เคียงกันมาก แทบจะครบตามที่ต้องการ


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

1. Performance ไม่ได้ดีระดับ Native แต่ก็ถือว่าไม่น่าเกลียดไปนัก

2. ไม่มี Interface Builder แต่ข้อนี้ก็แก้ได้ ด้วยมีคนเขียนตัว Convert มาให้แล้วครับ สำหรับ Titanium Mobile นะ เดี๋ยวไว้จะเอามาแนะนำกัน

3. หาข้อมูลยากเหลือเกินครับ ถ้าไม่ยอมจ่ายตังค์ จะส่ง Ticket ไปถามก็ไม่ได้ แต่เรามันพวก คิวบู๊ อยู่แล้ว เรื่องแค่นี้ ไม่ง้อก็ได้วะ !


เอาล่ะๆ มาดูข้อมูลในส่วนอื่นๆ บ้าง

สินค้าในตระกูลของ Titanium นั้นก็มีหลายตัวด้วยกันครับ ตามนี้

http://www.appcelerator.com/products/

ซึ่งถ้าสนใจจะจ่ายตังค์ก็เข้าไปดู แล้วตัดสินใจเลือกกันได้ตามด้านล่างนี้

http://www.appcelerator.com/products/plans-pricing/

แต่สำหรับผมใช้ Free ไปมันก็ใช้ได้เยอะแล้วน้าาา ไว้วันหลังอาจจะอุดหนุน แต่ไม่ใช้ตอนนี้ 555

 

ส่วนตัวที่ผมลองเล่นมีแค่

Titanium Desktop กับ Titanium Mobile

โดยที่ 2 ตัวนี้มีความแตกต่างกันในส่วนของ ปลายทางที่จะ Port ไปลงก็ชื่อมันก็บอกอยู่แล้วนะ โดยไอ้ตัวแรกมุ่งไปทาง Desktop อาทิเช่น Windows, Mac, Linux จริงๆ ไม่อาทิเช่นก็ได้ มันมีแค่นั้นแหละ 555

ส่วนอีกตัวมุ่งไปทาง Mobile คือ iOS กับ Android ส่วน RIM กับตัวอื่นๆ กำลังพัฒนา อยู่ครับ

 

ต่อไปนี้ผมจะพูดถึง Titanium Mobile เท่านั้นนะครับ เพราะ Desktop ผมยังไม่ได้ลองเล่นอะไรมาก ถึงขนาดเอามาบอกเล่าได้

โดยขั้นตอนติดตั้งจะมีคู่มือ ทั้งในส่วนของ Mac และ PC (Windows 7)

Download Link:
http://www.appcelerator.com/products/download


Installation Guide:

- Windows 7 (Android)

- Mac OS

ส่วนของ MAC นั้นผมลองเขียน เป็น iOS วิธีลงง่ายมาก ให้ลง Xcode 4 ก่อน จากนั้นให้ลง Titanium Studio ตาม ก็เป็นอันเสร็จ

(PS. ในส่วนต่อไปผมขอพูดถึงวิธีการเขียนหรือ ข้อมูลด้านอื่นๆ เป็น iOS นะครับ เพราะว่าผมยังไม่ได้ลองลง ตัว Android SDK เลยด้วยซ้ำ)

 

หลังจากที่เราลง Titanium Studio เรียบร้อยแล้ว เราก็จะได้ IDE ไว้ใช้งานพร้อมที่จะสร้าง Project แล้วครับ โดย IDE ที่ได้มาจากของ Free จะเป็น Aptana ที่มี Titanium SDK ฝังอยู่ในตัวให้เรียบร้อย (หน้าตาค่อนข้างมืดมน หน่อย แต่ตอนนี้ผมชินแล้ว)

หลังจากที่เราลงเสร็จ สิ่งแรกที่เราควรจะทำเลยคือ Download ตัวอย่าง Kitchen Sink มา แล้วค่อยๆ ไล่ดูทีละอัน

Get Start With Kitchen Sink

ซึ่งตัวอย่างที่เค้าให้มาดูง่ายมากๆ เลยครับ ที่นี้เราลองมาดูพร้อมๆกัน ว่าเราจะทำงานกับ Kitchen Sink ยังไง ?

1. ให้เรา New Mobile Project มาก่อนโดยที่ ทำการคลิกขวา ตรงพื้นที่ฝั่ง Document แล้ว เลือก

New -> Titanium Mobile Project


2. ให้ Download Kitchen Sink มา แล้วจับ โยกเข้าไปใน  Project เรา หรือว่าจะ Import เข้าไป ผลที่ได้ก็เหมือนกันครับ โดยจะได้ Tree ตามรูปด้านล่าง

3. จากนั้นให้เราลอง Run iPhone Simulator ขึ้นมาดู โดยกดไปที่ ตัวที่เป็น สามเหลี่ยม ปุ่ม Play นั่นล่ะ

4. สุดท้ายก็ได้ตัวอย่างมาลองแล้ว โดยจะประกอบไปด้วย Tab Group 4 Tabs คือ

4.1 Base UI

4.2 Controls

4.3 Phone

4.4 Platform

4.5 Mashups

5. โดยเราจะสามารถ รู้ได้ว่า ตัวอย่างนี้รันอยู่ที่ไฟล์ไหน ได้โดยดูที่ Console Log ประกอบครับ แล้วก็เข้าไปดูซิว่า เค้าเขียนแบบไหน มันถึงออกมาได้แบบนั้น

6. โดยการเขียนทุกครั้งเราจะต้องเริ่มจากไฟล์ app.js เป็นไฟล์แรก ซึ่งตามตัวอย่างนี้ ใช้ TabGroup เป็นตัวเริ่มต้นของ Application

 

เอาล่ะครับ เท่านี้ก็เป็นอันจบสำหรับการเริ่มต้นกับ Kitchen Sink ซึ่งเรื่องเทคนิคลึกๆ ยังต้องพูดกันอีกยาวครับ สำหรับตัวนี้ซึ่งการเขียน ยังไงวันนี้ผมก็ขอลาไปนอนก่อนล่ะครับ ฝันดี

 

Appendix

1. Titanium Mobile Document Guide

2. Titanium Mobile Q&A

3. Titanium Mobile API Docs

4. Titanium Mobile Programming Guides

5. Seven days with Titanium

6. Titanium Mobile on Mobiletuts+

7. Titanium Mobile on Stackoverflow

8. Building iPhone Apps with JavaScript using Titanium

9. Titanium Mobile Scripts on CodeCanyon (Paid)

10. Titanium Mobile on Vimeo (Media)

11. Titanium Mobile on YouTube (Media)

]]>
jQueryTips wrote a new story "ข้อมูลที่จำเป็นต้องรู้ก่อนเริ่มลงมือเขียน iOS Application". Sun, 26 Jun 2011 17:58:29 +0700 http://jquerytips.oscool.com/blogs/view/2372 http://jquerytips.oscool.com/blogs/view/2372 jQueryTips jQueryTips ก่อนที่จะลงมือเขียน iOS App นั้นเราต้องทำความเข้าใจก่อนว่า วิธีการเขียนนั้น มันไม่ได้มีวิธีการเดียว แต่มันมีถึง 3 วิธีด้วยกัน ซึ่งก็คือ Native, Web View, Hybrid โดยที่แต่ละตัวก็อาจจะมี ประเภทย่อยๆ แล้วก้ชนิดของมันลึกลงไปอีกบ้าง แต่ว่าไม่ใช่สาระสำคัญอะไร

ทีนี้ผมจะขออธิบาย ตามความเข้าใจแบบ งูๆ ปลา ของผมก่อน แล้วกัน ถูก ไม่ถูกยังไง ก็ขอให้เข้าใจไว้ว่า ผมมัน "มือใหม่"

1. Native App

App ประเภทนี้ก็คือ App ที่เขียนตาม Rules ของ Apple ล้วนๆ คือใช้ Xcode พัฒนาโปรแกรมด้วย Objective C แบบตรงๆ ซึ่งผลที่ได้ก็คือ Performance ดีเยี่ยม ความเสี่ยงที่จะไม่ได้รับการ Support เป็น 0 อภิสิทธิ์ เหนือชั้น

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

แต่ทว่าก็ไม่อยากให้ทิ้ง อยากให้เป็นตัวที่เราพยายามเรียนรู้ไป ในขณะที่กำลังเขียนในรูปแบบอื่นๆ

2. Web View

อันนี้เป็นตัวเลือกในกรณีที่เราต้องการ App แบบเร่งด่วน แล้วก็ไม่ต้องการลูกเล่นอะไรมากมายนัก ไม่จำเป็นต้องติดต่อกับ Feature ภายในตัวเครื่อง ภาษาที่เขียนก็ Web Skill ล้วนๆ ครับ เขียนเสร็จก็เอา Native เรียก URL ตรงๆ มาเลยก็เสร็จแล้ว ไม่จำเป็นต้อง Learning อะไรใหม่เลย ถ้าคุณเป็น Web Dev อยู่แล้ว

โดยที่คุณอาจจะมีตัวช่วยหน่อยก็คือพวก Mobile Web Framwork อย่าง jQ Touch, jQuery Mobile, Sencha Touch เพื่อให้มันดูโปรขึ้นมาอีกนิด

ข้อเสียก็คือ App มันดู ป๋องๆ แป๋ง ใช่มั้ยล่ะ ? แล้วก็ติดต่อกับ Feature เช่นพวก  กล้อง, Location Base, Network อะไรพวกนี้ไม่ได้เลย !!!!

แล้วก็ความเร็วของ App มันจะไปผูกกับ Web Server แทบจะ 100% เลยทีเดียว แต่มันก็สะดวกและเร็วมากๆ คุณอาจจะเอามาเป็นตัวเลือกแรก ในการหัดทำแรกๆ ก็ไม่เสียหายหรอก

3. Hybrid App

App ประเภทนี้ชื่อมันก็บอกอยู่แล้วว่าเป็นลูกผสม โดยที่คุณ สามารถจะใช้ Web Skill โดยที่ยังติด่อกับ Feature ในตัว iOS Device ได้อีด้วย

โดยหลักการของมันก็คือ คุณจะเขียนอยู่ใน Framwork หรือ SDK อีกทีนึง ด้วยเทคนิคนี้ Web Skill ของคุณจะโดยหั่นเหลือแค่ ทักษะในการใช้ HTML5 + Javascript ถ้าจะเขียนพวก Server Side Script คุณจะต้องทำออกมาเป็น Web Service เอง

หลักการของมันก็คือ ไฟล์ HTML + JS ทั้งหมดของคุณจะถูกฝังลงไปเป็นตัว App ด้วย แล้วก็โดนเรียกจากภายในตัวเองเท่านั้น ถ้าต้องการส่ง  หรือ รับ Data จากภายนอก จะส่งกันผ่าน XHR (จริงๆ คุณจะเรียก URL ออกมาก็ได้ แต่ถ้าทำแบบนั้น AppStore จะไม่มีทางรับคุณเข้าไปอาศัยด้วย 555)

ส่วนการติดต่อกับ Feature ภายในจะใช้ SDK ที่ใช้งานร่วม ที่มี API เป็น Javascript Syntax  ให้ใช้งาน

Framework ประเภทนี้ก็จะมีพวก PhoneGap, Titanium Mobile, NimbleKit, etc.

ข้อดีก็คือ ใช้เวลาศึกษาไม่นานเลย เพราะว่า Web Dev ส่วนมากจะมี Skill ทาง Javascript อยู่บ้างแล้ว ไม่มากก็น้อย ไม่น้อยก็ควรจมีบ้าง 5555

ส่วนมาก Framework พวกนี้จะเขียนที่แล้วออกมาได้หลาย Device เลยเช่น iOS, Android, RIM, Window Phone 7*, Symbiam*

* ส่วนมากมักจะไม่สมบูรณ์

แล้วก็สามารถทำงานได้เร็วกว่า Web View เพราะว่าเรียกไฟล์ภายในตัวเอง ที่สำคัญสามารถเรียกข้อมูล ออกมาภายนอก โดยไม่กังวลเรื่อง Cross Domain (ก็ App มันไม่มี Domain นี่หว่า) แล้วก็ API พวกนี้ส่วนมากจะมีชุดของ Local Storage มาให้ใช้เป็น Basic อยู่แล้ว 5MB ทำให้ง่ายในการจัดเก็บข้อมูล

แล้วข้อเสียล่ะ ?

มันก็ไม่เร็วเหมือน Native App Performance ก็ต่ำกว่า แล้วก้มี เปอร์เซ็นต์บ้างที่เวลา OS มันอัพเดท เราอาจจะต้องมารอ ชุด Framework ครอบพวกนี้ อัพเดท เพื่อที่จะได้ใช้ Feature ใหม่ๆ

 

เอาล่ะ นี่คือคร่าวๆ ......

 

แต่ทีนี้ในจำนวนรูปแบบการเขียน Hybrid มันก็มีบางแบบที่น่าสนใจมาก ก็คือ แทนที่มันจะเป็น Hybrid แบบปกติ แต่ยังเสือกใช้ Native UI ได้อีก เลยทำให้ App เนียนมากขึ้นไปใหญ่อาทิเช่น Titanium Mobile, NimbleKit*

* NimbleKit  ผมไม่ได้ลองเล่น เลยไม่รู้ว่ามันจะจริงมั้ย ??

ถ้าอยากดูว่ามันเนียนแค่ไหน ลองโหลด Wunderlist จาก AppStore มาดู ตัวนั้นและ App ที่มีชื่อเสียง แล้วก็ทำจาก Titanium Mobile

 

เกริ่นกันไว้แค่นี้ก่อน ระหว่างนี้ใครสนใจก็ไปลองศึกษาเพิ่มเติมนะครับ ครั้งหน้าผมจะเข้าสู่เรื่องของ Titanium Mobile, Tiranium Studio กันเลย

]]>
jQueryTips wrote a new story "เขียน iOS เริ่มต้นจากตรงไหนดี ?". Thu, 23 Jun 2011 01:03:02 +0700 http://jquerytips.oscool.com/blogs/view/2352 http://jquerytips.oscool.com/blogs/view/2352 jQueryTips jQueryTips กรูยังไม่ตายยยยยยยย .....

 

เริ่มต้นแบบนี้ก่อนเลย เพราะหายไปนานมากๆ จนจำไม่ได้แล้ว อัพเดทครั้งสุดท้ายเมื่อไหร่ 555

พอดีตอนนี้อยู่ในช่วงการเก็บตัวฝึกซ้อม เพื่อเปลี่ยนสายอาชีพ อิอิ 

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

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

สำหรับผมเองนั้น จับงานสายเว็บมาตลอด ถ้านับเป็นปีนี่มันจะบอกอายุเกินไป ข้ามไปเลยๆ 555

ตอนนี้พอจะหันมาทำเรื่องมือถือบ้าง ต้องเปลี่ยนภาษาที่เขียน ไปลอง หยิบๆ จับๆ หัดๆ Objective C มาอยู่พักใหญ่ๆ (4 วัน) ก็เห็นว่าไม่เข้าท่าแน่ มันช้าเกิน หัวไม่ค่อยรับอะไรเลย 555

 

ก็เลยลองหาวิธี อื่นที่มันสามารถจะเขียน iOS ได้ อาทิเช่น HTML 5 เป็นต้น แต่ก็อยากติดต่อกับอุปกรณ์มันได้ด้วยนี่นา แค่ให้ทำ WebView แบบปกติๆ เหรอ มันกระจอกชะมัด T__T 

หลังจากนั่งๆ นอนๆ เที่ยวเล่นอยู่พัก ก็ไปลองพยายามหาใหม่ ทีนี้ไปเจอ Flex Builder for PHP เออ แม่งเข้าท่าเขียน PHP Build ออกมาเป็น Native App เจ๋งๆ สุดยอด พระเจ้า !!!!!

แต่ก้ต้องผิดหวัง เดินคอตกออกมา เพราะมันเหมือนหลอกลวง ยังไงชอบกล ใครเคยลองแล้วจะรู้ 5555

หรือกรูจะต้องเขียน Objective C จริงๆ บอกตามตรง "ขี้เกียจจะเลิร์น" แต่ทว่า ชีวิตต้องไม่สิ้นหวังสิวะ 

 

Google... !!! Google ! Google ! 

 

หาอยู่พักใหญ่ๆ ไปเจอ วิธีเขียนอีกแบบ เค้าเรียกว่า Hybrid โดยหลักการคร่าวๆ มันเป็นดังนี้ 

เขียน Template ด้วย HTML 5 แต่ว่า โคด HTML ทั้งหมดต้องฝัง ลงไปในเนื้อเดียวกับ App แล้วจะมีพวก ตัวช่วย อาทิเช่น PhoneGap เป็นตัวติดต่อ กับ มือถือ เช่น กล้องถ่ายรูป, contact, network เป็นต้น โดยที่จะมี API ฝังในตัว เขียนเป็น js ที่ดูแล้วง่ายมากๆ 

เอาล่ะ ที่นี้เราได้ตัวติดต่อแล้ว ต่อไปหน้าตาล่ะ อยากให้มันเนียนๆ หน่อยเอาไงดี เลยไปค้นๆ เจอไอ้นี่อีก Sencha ชื่อเหมือนชาเขียวเลย  555

ต่อจากนั้นก็ลองเล่นตาม Step เทพเค้าเลยครับ

A Sencha Touch MVC application with PhoneGap

ทีนี้ใช้เวลาศึกษาอยู่ 1 อาทิตย์เต็มๆ จนพอจะเขียนได้คล่องบ้าง อยากบอกว่าตอนศึกษาแม่งโครตจะลำบาก กว่าจะ Render กว่าจะทำนู่นทำนี่ได้ อ่านจนจะเป็นไข้เลย 

สุดท้ายก็เขียนออกมาแล้วเอาไปเทสต์กับมือถือดู "WTF" ทำไม มันแปร่งๆ ไม่เนียนเลย Rotate  กลับไปกลับมา แม่งมี Space โผล่มาอีกละ -*-

ตอนนี้ในหัวมีแต่คำถาม 

หรือกูจะต้องเขียน Objective C

 

เอาวะ ตอนหาข้อมูลเรื่อง Sencha มี Keyword อีก 2-3 ตัวแถมมาด้วย ก็ลองนึกๆ ดูมันคืออะไรบ้าง หนึ่งในนั้นคือ 

NimbleKit

ก็ไปลองๆ ทีนี้สั้นหน่อย ลองได้แค่ 30 นาที รู้สึกไม่ถูกชะตาเท่าไหร่ ไปลอง KW ตัวต่อไปดีกว่า นั่นก็คือ พระเอกขี่ม้าขาว (ในช่วงนี้)

Appcelerator Titanium Mobile

ลองไปได้ 1 ชั่วโมงเต็มๆ เพระว่าตอนนั้นมันก็ดึกมากแล้ว ง่วงนอนเต็มที่ แต่ในขณะที่ลองนั้น บอกได้คำเดียวว่า ค่อนข้างพอใจ เนื่องจาก 

ใช้ Syntax  เป็น JS ล้วนๆ แต่ผลลัพธ์ เป็น Native App ทั้ง UI ทั้ง Animate เนียนมากๆ เพราะเนื่องจากมันเป็น Native ก็เลยไปนอน (เอ้ยไม่เกี่ยว แต่ตอนนั้นทำแบบนี้จริงๆ 555)

 

วันรุ่งขึ้นมาหาข้อมูลต่อ ทั้งเรื่อง การ Approve จาก AppStore ว่ามีปัญหามั้ย ทั้งเรื่อง Performance ทั้งช่วง Gap ของ การอัพเดท iOS ว่าต้องรอ API มันอัพเดทตาม นานแค่ไหน พอได้ข้อมูลมาประกอบการตัดสินใจก็เลย 

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

ก้คิดไว้ว่าตัวนี้น่าจะมาเป็น "อัศวินม้าขาว" ได้พอถ่วงเวลา ให้ศึกษา Objective C ไปพลางๆ ได้บ้าง ยังไงก็ รอดูบทความถึงวิธีการเขียน รวมไปถึง การประยุกต์ ใช้งานกับ Web Service ได้ในตอนต่อๆ ไปนะครับ กับ jQuery Mini Series: Mobile ที่ไม่ใช่  jQuery Mobile 555

 

สำหรับวันนี้ ตัวใครตัวมันนะครับ 

 

]]>
jQueryTips wrote a new story "NoSQL กับ Mongo DB เขียนง่ายสบายจายยยย". Tue, 05 Apr 2011 18:15:18 +0700 http://jquerytips.oscool.com/blogs/view/1606 http://jquerytips.oscool.com/blogs/view/1606 jQueryTips jQueryTips

สวัสดีครับ ช่วงนี้ห่างหายจากการอัพเดทไปเลย พอดีติดเกมส์ 555++

จริงๆ แล้ววันนี้มีหลายเรื่องที่อยากจะมาเล่าสู่กันฟัง อาทิเช่น

NodeJS
Facebook Offline Message API
CI 2.0.1
วิธีการทำ Caching ของ Facebook
Cross Domain Cookie
วิธีการใช้ domain, subdomain map เข้ากับ user ของเราผ่าน CI, etc....

แต่ก็สรุปมาเลือก MongoDB ที่เป็น NoSQL โดยไม่มีเหตุผลอะไรรองรับ นอกจากว่า "มันเขียนอธิบายง่ายสุด" ส่วนเรื่องอื่นๆ ใครสนใจเรื่องไหน ก็บอกกันได้นะครับ จะได้มาไว้เขียนในคราวหน้า

เอาล่ะๆ มาเริ่มกันเลยดีกว่า

NoSQL จริงๆ แล้วก็ต้องถือเป็น ฐานข้อมูลชนิดนึง ซึ่งจะแตกต่างจาก Database พวกภาษา SQL ทั้งหลาย คือตัวมันจะเป็น ฐานข้อมูลที่ไม่มีความสัมพันธ์กัน เพราะฉะนั้น ลืมเรื่อง relation ไปก่อน สักพัก

แล้วก็สามารถรองรับกับจำนวนข้อมูลที่มากมายได้ โดยยังทำงานได้เร็ว เพราะไม่ต้องมีความสัมพันธ์ใดๆ ฉะนั้น ไม่ต้องกังวลว่า Index จะทำงานมั้ย มันยังไงก็ทำงาน

แล้วก็ข้อดี (รึเปล่า) คือมันไม่มี structure คลุม ไม่ต้องมาสร้าง fields เตรียมไว้ก่อน อยากเก็บยังไๆงก็เก็บ แต่ก็ควรคิดให้ดีๆ ซะก่อน

สามารถขยาย scale ออกได้ง่ายๆ เพราะเป็นการต่อตรง เวลาข้อมูลเยอะเข้าๆ ก็เพิ่มเครื่องๆๆๆๆๆ เข้าไปเรื่อยๆ อันนี้ดีสุดๆ

เว็บไซต์ระดับโลกที่มีข้อมูล มหาศาลยังไงก็ต้องออกแบบใน ลักษณะนี้ทั้งนั้น อาทิ Facebook, Twitter เพราะจำนวนข้อมูล ไหลเข้า ไหลออก มีมากมายมหาศาล

NoSQL ก็มีมากมายหลายตัวอีก แต่ที่วันนี้จะมาพูดกันนะ คือ MongoDB เอาเป็นเชิงปฎิบัติ หรือการใช้งานกันเลยดีกว่า เรื่อง ทฤษฎี ไม่ค่อยจะถูกกับผมนัก ไอ้ที่เขียนไปข้างบน ถูกบ้าง ผิดบ้างก็ขออภัยด้วยนะ อย่าว่ากันเลย

การใช้งานนั้น ถ้าเขียนผ่าน PHP Framework ก็เอา Google หาได้เลย มีคนเขียน client มาเยอะแยะอยู่แล้ว

แต่ทีนี้ผมจะมาพูด เอาเป็นใช้งานผ่าน PHP โดยตรงเลย

สิ่งที่เราต้องมีในวันนี้ก็คือ

1. MongoDB
http://www.mongodb.org/downloads

2. PHP Mongo Extension
http://php.net/manual/en/mongo.installation.php

เท่านี้แหละครับ ที่เราต้องมีพิเศษกว่าครั้งอื่น ส่วนวิธีการลง มันมีบอกไว้อยู่แล้วตามลิ้งค์เลย

พอเราได้มาครบติดตั้งเสร็จเรียบร้อย ก็มาเริ่ม start mongo กันก่อน โดยเปิด cmd ขึ้นมา (ผมเขียนผ่าน Windows)

d:PHPCodedevelopmentmongomongodbbinmongod.exe --dbpath d:PHPCodedevelopmentmongoStorage

แนะนำให้เขียนเป็น .bat ไว้เลย เวลา start จะได้ไม่เสียเวลา

โดยตัวแรกจะเป็นที่อยู่ .exe ของ mongodb ที่เราโหลดมา

ตัวที่สองจะเป็น ที่อยู่ที่จะเป็น root ของการจัดเก็บข้อมูล

 

ตัวอย่างการ connect

 

// connect mongo on localhost
$m = new Mongo;

// select database
$db = $m-&gt;people;

// select collection
$collection = $db-&gt;person;

 

ให้มองเหมือน db ก็ได้คือต้อง conenct -> select db -> select table

อันนี้ผม conenct ผ่าน localhost เลยไม่จำเป็นต้องระบุ IP:PORT ลงไป

 

ตัวอย่างการ Insert

 

$insert = array(
	'name' =&gt; $_POST['name'],
	'lastname' =&gt; $_POST['lastname'],
	'age' =&gt; $_POST['age'],
	'comments' =&gt; array()
);
$collection-&gt;insert($insert, true);

$m-&gt;close();

 

 

โดยค่า last insert id เราสามารถ get ออกมาด้วยคำสั่งนี้

 

$insert['_id']

 

 

ตัวอย่างการดึงข้อมูลทั้งหมด พร้อม where case, pagination limit

 

$docs_per_page = 5;

$page = isset($_GET['page']) ? $_GET['page'] : 1;
$q = isset($_GET['q']) ? $_GET['q'] : "";


$m = new Mongo;
$db = $m-&gt;project;
$collection = $db-&gt;users;

$criteria = array();
if (isset($q{0})) {
	$criteria['first_name'] = new MongoRegex('/' .$q . '/i');
	//$criteria['last_name']['$or'] = new MongoRegex('/' .$q . '/i');
}
$fields = array('email', 'first_name', 'created_at');

$skip = (int) ($docs_per_page * ($page - 1));
$limit = (int) $docs_per_page;

$cursor = $collection-&gt;find($criteria, $fields);
$cursor-&gt;sort(array('created_at' =&gt; -1))-&gt;skip($skip)-&gt;limit($limit);

$total_result = $cursor-&gt;count();
$total_page = (int) (ceil($total_result/$docs_per_page));

$m-&gt;close();

 

 

ตัวอย่างการดึงข้อมูลแบบ Record เดียว

 

$m = new Mongo;
$db = $m-&gt;people;
$collection = $db-&gt;person;
$criteria = array(
	'_id' =&gt; new MongoId($id)
);
$doc = $collection-&gt;findOne($criteria);

 

 

ตัวอย่างการ Update

 

// connect mongo on localhost
$m = new Mongo;

// select database
$db = $m-&gt;people;

// select collection
$collection = $db-&gt;person;

$criteria = array(
	'_id' =&gt; new MongoId($id)
);

$doc = array(
	'name' =&gt; $_POST['name'],
	'lastname' =&gt; $_POST['lastname'],
	'age' =&gt; $_POST['age'],
	'comments' =&gt; array()
);
$collection-&gt;update($criteria, $doc);

$m-&gt;close();

 

 

เท่านี้แหละครับ Syntax ไม่มีอะไรซับซ้อนเลยสักนิด สังเกตุ ดีๆ มันทำงานคล้ายๆ กับ database ปกติ แหละ จริงๆ แล้ว ผมมีตัวอย่างเว็บ ที่อยากให้ไปลองอ่านกัน ซึ่งเข้าเขียน เทียบกับ SQL ให้เราเห็นเลยว่า Flow มันไม่หนีกันเลย แถมยังไม่ต้องมาคิดเรื่อง Relation ให้ปวดหัวอีกด้วย

http://www.dealtaker.com/blog/2010/05/12/php-mongodb-sitting-in-a-tree-part-1/

http://www.shift8creative.com/blog/mongodb-queries-with-lithium-part-two

ไอ้ 2 ลิ้งค์ข้างบนอ่านแล้วจะทำความเข้าใจได้ดีมากๆ แนะนำเลย

 

ส่วนตรงนี้ถือเป็นข้อมูลที่มีประโยชน์เพิ่มเติมนะครับ

http://www.slideshare.net/kbanker/mongodb-schema-design

 

อันนี้เป็น Client ที่ใช้กับ CI ครับ (โดยส่วนตัวไม่คิดว่าจะมีประโยชน์นัก เพราะว่า มันแค่ตัวครอบ ที่เหมือนยังเขียนไม่เสร็จซะมากกว่า)

https://bitbucket.org/alexbilbie/codeigniter-mongo-library/wiki/Home

 

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

]]>