Monday, October 24, 2011

Configuring PHP Extension on Windows - A simple way


There has been too many problem reported in our forum about not able to configure one particular extension. The problems are many:
  • Configuring a non-compatible version of the extension
  • Missing some dependent DLL
  • Trying to use thread safe version of the extension DLL  for non thread safe PHP build and vice-versa
If you have configured a PHP extension and you can't see it loaded, I generally run the command (assuming your PHP is installed at 'C:\Program Files\PHP')
'C:\Program Files\PHP\php-cgi.exe' -v from the command prompt.
This really helps in catching some error.
So what's the best way to configure a PHP extension. I would say if the extension you are trying to install is available as part of PHP MSI, it is the best idea to use the PHP MSI to configure your extension. There is no manual step involved and all right dependent DLL will also get installed. Plus your PHP.INI file gets updated automatically. Now I am going to tell you how to achieve this from a PHP MSI UI. Let me warn you this is for novice user. Expert ones can just skip this. So here are the steps:
  • Go to Control Panel
  • Click on Add/Remove Program (Or, Uninstall a program)
  • Select PHP MSI and click on 'Change'. Remember you should have installed PHP using the PHP MSI. If you have installed it using the ZIP file this won't work.
  • You will see the below UI.
image
  • Click on Next, following UI will appear.
image
  • Click 'Change'
image
  • Select 'IIS FastCGI'
image
  • Chose the extension you want to install and click 'Next'.
image
  • Click on 'Change'
  • Click on 'Finish' on next screen and you are done.
So you now know how easy it is to install a PHP extension using the MSI.
Hopefully this will help you in setting up your PHP extension. Thanks for the patient reading and good bye.

ref : http://blogs.iis.net/donraman/archive/2009/10/16/configuring-php-extension-on-windows-a-simple-way.aspx

IIS 6.0 with FastCGI + PHP

ปกติประสิทธิภาพในการรันเว็บที่เป็นภาษา PHP บน IIS จะสู้บน apache ไม่ได้ เพราะบน IIS มีรูปแบบการสั่งงานที่รองรับแบบ CGI ที่ทำงานได้ช้ามาก หรือจะให้ดีหน่อยก็สามาถใช้แบบ ISAPI ได้ แต่ก็ทำให้เว็บ PHP ทำงานได้ไม่ถูกต้อง มาวันนี้ไมโครซอฟท์พึ่งจะได้ออกส่วนเพิ่มเติมของ IIS ให้สามารถใช้ FastCGI ได้แล้ว ประสิทธิภาพที่ดีขึ้นแบบเห็นได้ชัด การทำงานก็ปกติ กิน ram น้อยไม่เหมือนตอนรันแบบ ISAPI มาดูวิธีติดตั้งกัน

* สมมติว่าได้ติดตั้ง php ไว้แล้วที่ c:\php และมีไฟล์ php-cgi.exe
อันดับแรกไปโหลด FastCGI Handler for IIS 6.0 มาก่อน
fcgisetup32.msi
โหลดเสร็จแล้วให้เีรียกติดตั้งเลย ไม่มีอะไรมากมาย
เมื่อติดตั้งแล้วจะพบ 3 ไฟล์นี้ C:\Windows\system32\inetsrv\
  • fcgiext.dll
  • fcgiext.ini
  • fcgiconfig.js
ขั้นตอนต่อไปเพิ่ม fcgiext.dll ลงใน extension mapping สำหรับไฟล์ .php
IIS > Web Sites > properties > Home Directory > Configuration… > Add…

ต่อไปเปิดไฟล์ fastcgiext.ini ขึ้นมาแก้ ใส่ตอนท้ายๆ ไฟล์
[Types]
php=PHP

[PHP]
ExePath=c:\php\php-cgi.exe

สำหรับ option อื่นสามารถดูได้ในไฟล์ fsgiext.ini

ขั้นตอนสุดท้ายให้แก้ไขไฟล์ php.ini โดย แก้บรรทัดนี้
fastcgi.impersonate = 1


RESTART IIS เสร็จ ก็ใช้งานได้เลย

จะย้าย data path ใน MySQL 5.0 อย่างไร?


         หลักการทั่วไปของการย้าย data path บน MySQL 5.0 นั้น อาจดูซับซ้อนกว่า MySQL 3.23 ที่คุ้นเคย หรือกระทั้ง MySQL 4 ตัวผมเองนั้นผมเล่นจาก MySQL 3.23 แล้วว๊าปมาเป็นเวอร์ชัน 5.0 เลย เพราะไม่ชอบเวอร์ชัน 4 เอาเสียเลย เนื่องจากเป็นเวอร์ชันครึ่งผีครึ่งคนเกี่ยวกับภาษาไทย สมัยที่ผมยังเช่า hosting ชาวบ้านเขาที่ us-based server ผมเจอปัญหา 108 จริงๆ ครับ (โดยเฉพาะเรื่องภาษาไทย) หลังๆ ไม่เจอแล้วครับ เพราะมีเซิร์ฟเวอร์เป็นของตนเองแล้ว สั่งเองทุกอย่างได้ดังใจหมาย กว่าจะเก็บเล็กผสมน้อยจนพอมีเงินมาซื้อเซิร์ฟเวอร์เป็นของตัวเองได้ ก็เล่นเอาเหนื่อยชนิดหืดขึ้นคอเหมือนกันครับ :)
          สำหรับบน MySQL 5.0 นั้นสนับสนุน utf-8 (รหัสอักษร unicode เต็มพิกัด) ดังนั้นคุณจะไม่เจอปัญหาในการเก็บข้อมูลหลายๆ ภาษาลงบนฟิลด์เดียวกัน ไม่ต้องมานั่งแยกฟิลด์ของเทเบิลเพื่อเก็บแยกข้อมูลเหมือนในเวอร์ชันก่อนๆ เช่น ไทย อังกฤษ เยอรมัน  3 ภาษาฟิลด์เดียวกัน  อย่างนี้ไม่มีปัญหา เพราะถ้าไม่ใช่ระบบ unicode แล้ว สระภาษาไทยมันจะไปตีกับสระของภาษาเยอรมัน กลายเป็นไม้ตรี ไม้จัตวาปรากฏบนภาษาเยอรมันมั่ง หรือภาษาอะไรก็ตาม ที่ดันทะลึ่งไปมีโค้ดตรงกับสระของภาษาไทย ภาษานั้นจะมีปัญหาหมดครับ

วกกลับเข้าเรื่องกันต่อ หลักการติดตั้งให้ MySQL 5.0 มันเก็บ data path แยกไปตามที่ต้องการให้ทำดังนี้ครับ
          1. ในการติดตั้ง MySQL 5.0 ถ้าอยากให้ data path เก็บอยู่ที่ไดรฟ์ไหน ให้ติดตั้ง MySQL ไว้ที่ไดรฟ์นั้น เช่น ในคอมพิวเตอร์เรามีไดรฟ์ C และไดรฟ์ D เราอยากให้ข้อมูล data ของ MySQL อยู่ที่ไดรฟ์ D ก็ให้เราติดตั้ง MySQL ไว้ที่ไดรฟ์ D เช่น D:\MySQL5 หลังจากนั้น คุณผู้อ่านก็ติดตั้ง MySQL ไปตามปกติที่เคย (อย่าลืมสั่ง stop Apache ก่อนนะ แล้วก็อย่าลืมปิด Firewall application ก่อนจะเริ่มติดตั้ง MySQL ด้วยนะครับ โดยเฉพาะพวก Firewall application ทั้งหลายมันจะดัก port ไว้ ทำให้ MySQL ติดตั้งไม่ได้)
           2. พอติดตั้ง MySQL เสร็จแล้ว ให้ไปเปิดไฟล์ my.ini แล้วมองหาบรรทัดนี้ครับ (ถ้าคุณติดตั้ง MySQL ใน D:\MySQL5 ไฟล์ my.ini จะอยู่ที่                     
D:\MySQL5\my.ini)
#Path to the database root
datadir="D:/MYSQL5/Data/"
จากนั้นให้แก้เป็น path ที่คุณต้องการ เช่นผมอยากจะเก็บไว้ที่ d:/mysql_data/ ก็ให้พิมพ์แบบข้างล่างนี้ 
ข้อควรระวังให้ใช้ forward slash "/" นะครับ ไม่ใช่ back slash "\"
#Path to the database root
datadir="D:/mysql_data/"

          3. ถ้าคุณต้องการปรับแต่งเพิ่มเติม ก็ให้ดูบรรทัดต่อไปนี้เพิ่มด้วยก็ได้
# The default character set that will be used when a new schema or table is
# created and no character set is defined
default-character-set=utf8
บรรทัดข้างบนนี้ให้กำหนด default character set เป็น utf-8 ถ้าไม่ชอบก็เปลี่ยนได้ (แนะนำว่าเป็น utf8 นั้นดีที่สุดแล้วครับ)
# The default storage engine that will be used when create new tables when
default-storage-engine=INNODB
ถ้าคุณไม่ชอบการกำหนด default engine เป็น INNODB ก็สามารถเปลี่ยน MyISAM ได้ ดังบรรทัดข้างล่าง
# The default storage engine that will be used when create new tables when
default-storage-engine=MyISAM
ความต่างของ INNODB กับ MyISAM ก็คือ MyISAM ทำงานได้เร็วกว่า แต่ไม่สามารถทำ loop back transaction ได้ ถ้าใช้เป็น INNODB จะสามารถทำ loop back transaction ได้ กรณีของ INNODB มักนิยมใช้กับ transaction ที่เกี่ยวกับระบบการเงิน หรือการชำระเงินเป็นต้น
เมื่อปรับ config เสร็จเรียบร้อยแล้วก็สั่ง save ไฟล์

         4. ไปที่โฟลเดอร์ D:\MYSQL5\data แล้ว copy ทั้งหมดที่มีในนั้น ไปไว้ที่ D:/mysql_data/"
(อย่าลืมสั่ง folder option ใน windows ให้แสดง hidden file กับ hidden system file ก่อนนะครับ ไม่งั้นจะมองไม่เห็นไฟล์อะไร)

ถ้า copy ถูกต้อง จะประกอบไปด้วยโฟลเดอร์ชื่อ mysql และ test แล้วก็มีไฟล์ ib_logfile0, ib_logfile1, ibdata1 และ microsof-xxxx (xxxx คือค่าที่ผันตามเครื่องคุณ)

         5. จากนั้นไปที่ start->setting->control panel->Performance and Maintenance->Administrative Tools->Services

พอเปิดส่วน Services ขึ้นมาแล้ว ให้มองหาบรรทัดที่เขียนว่า MySQL จากนั้นก็ drag ขวาที่บรรทัดนี้แล้วสั่ง stop แล้ว ค่อย start ใหม่

         6. ลองเปิดดู http://localhost/phpmyadmin แล้วลองสร้าง table หรือ database อะไรก็ได้ แล้วไปดูที่ d:/mysql_data ว่ามีชื่อ table หรือ database ขึ้นตามนั้นไหม ถ้ามีก็เป็นอันว่าโป๊ะเช๊ะ ok เรียบร้อยแล้วหละครับ 

Tuesday, September 13, 2011

Both DataSource and DataSourceID are defined on ‘GridView1′. Remove one definition. – Bind multiple datasources to a gridview control


Both DataSource and DataSourceID are defined on ‘GridView1′.  Remove one definition.
OK, so this is the message that you get most of the times when you try to bind your gridview or any other bindable controls, to multiple DataSources.
 It happens most of the times when you bind your GridView control to an ObjectDataSouce or SqlDataSource on the design surface and then you try to bind the same GridView in code behind using the manual coding and sometimes it becomes necessary to do so in the scenarios of searching and manual paging etc.
(Binding to ObjectDataSource)




(Binding to manual DataSource)



GridView1.DataSource = null;
GridView1.DataSource = myDataTable;
GridView1.DataBind();
This is not going to solve the problem, the simples workaround is to set theDataSourceID to null.
GridView1.DataSourceID = null;   // String.Empty
GridView1.DataSource = dt;
GridView1.DataBind();
now this is going to work perfectly fine but DataGrid required a page developer to write custom code to handle simple operations such as paging, sorting, editing or deleting data, the GridView control can automatically handle these operations provided its bound data source control supports these capabilities and we know that this kind of custom binding will kill any chances to automate your GridView to handle all these operations automatically.
Simplest way to resolve this issue is to display your required data to the client and then bind back the GridView to your original datasouce by setting the DataSourceID to null again. That will bring back all your automation functionality back to the GridView.

Label vs. Literal in Asp.net


ใน ASP.NETจะมีเว็บคอนโทรลอยู่สองตัวที่ทำหน้าที่คล้ายๆกันคือแสดงผลส่วนที่เป็นข้อความปกติ Label และ Literal คำถามที่เกิดขึ้นคือ เมื่อไหร่ควรจะใช้ Labelและเมื่อไหร่ควรจะใช้ Literal
ข้อแตกต่างที่เห็นได้ชัดระหว่าง Label และ Literal จะแสดงให้เห็นด้วยตัวอย่างง่ายๆคือ
<asp:Label ID="TestLabel" runat="server">Label</asp:Label> <asp:Literal ID="TestLiteral" runat="server">Literal</asp:Literal> 
ซึ่งจะให้ผลลัพธ์เป็น
<span id="TestLabel">Label</span>
Literal
ซึ่งจะเห็นว่าผลลัพธ์ที่ได้นั้นแตกต่างกันตรงที่ Label มี span ครอบแต่ Literal ไม่มี และเมื่อดูจากต้นไม้การสืบทอด จะเห็นว่า Literalนั้นสืบทอดมาจากคลาส System.Web.UI.Control แต่ Label นั้นสืบทอดมาจากคลาสSystem.Web.UI.WebControlทำให้สามารถควบคุมรูปแบบการแสดงผลพวกสไตล์ต่างๆได้ นอกจากนี้ Label ยังมีประโยชน์อีกอย่างที่ไม่ค่อยมีคนรู้กันก็คือ ใช้สำหรับสร้าง tag Label นั่นเอง
<asp:Label id="label" AssociatedControlId="textbox"  Text="Username" runat="server" />  <asp:TextBox id="textbox" runat="server" /> 
จะได้ผลลัพธ์เป็น
<label for="textbox">Username</label> <input type="textbox" name="textbox" value="" /> 
ในทางกลับกัน Literal ก็มีข้อดีที่ช่วยให้โค้ด HTMLที่ได้นั้นสะอาดและเรียบร้อยกว่าการใช้ Label ซึ่งจากตัวอย่างแรกจะเห็นว่าLabel ให้ผลลัพธ์ที่มีจำนวนตัวอักษรมากกว่า Literal ถึง 28 ตัวอักษร
จากความแตกต่างข้างต้นก็จะได้หลักการใช้งานคร่าวๆคือ
ใช้ Literal เมื่อ
  • แสดงผลข้อความทั่วๆไป ซึ่งดีกว่าการฝังข้อความลงไปตรงๆเพราะสามารถนำไปใช้ทำ Localization ได้ทันที
  • สร้างสคริปต์
  • ใช้ในจุดที่ไม่ต้องการให้มี span ครอบ เช่น <title>, <meta> หรือ <style> เป็นต้น
ใช้ Label เมื่อ
  • สร้าง label สำหรับ input ต่างๆ
  • สร้างข้อความที่ต้องการเปลี่ยนแปลงสไตล์
ส่วนตัวแล้ว แนะนำให้หลีกเลี่ยงการใช้งาน Label เพราะผลลัพธ์มันเปลือง และน่าเกลียดกว่า
ความจริงแล้วยังมีคอนโทรลอีกหนึ่งตัวที่ทำหน้าที่เหมือน Literal คือLiteralControl ข้อแตกต่างของสองคอนโทรลนี้คือ LiteralControlจะไม่เก็บข้อมูลไว้ใน ViewStateทำให้ค่าของพร็อพเพอร์ตีย์ต่างๆไม่ถูกจำข้าม Request

Sunday, September 11, 2011

String Format for Double [C#]


The following examples show how to format float numbers to string in C#. You can use static method String.Format or instance methods double.ToString and float.ToString.

Digits after decimal point

This example formats double to string with fixed number of decimal places. For two decimal places use pattern „0.00“. If a float number has less decimal places, the rest digits on the right will be zeroes. If it has more decimal places, the number will be rounded.
[C#]
// just two decimal places
String.Format("{0:0.00}", 123.4567);      // "123.46"
String.Format("{0:0.00}", 123.4);         // "123.40"
String.Format("{0:0.00}", 123.0);         // "123.00"

Next example formats double to string with floating number of decimal places. E.g. for maximal two decimal places use pattern „0.##“.
[C#]
// max. two decimal places
String.Format("{0:0.##}", 123.4567);      // "123.46"
String.Format("{0:0.##}", 123.4);         // "123.4"
String.Format("{0:0.##}", 123.0);         // "123"

Digits before decimal point

If you want a float number to have any minimal number of digits before decimal point use N-times zero before decimal point. E.g. pattern „00.0“ formats a float number to string with at least two digits before decimal point and one digit after that.
[C#]
// at least two digits before decimal point
String.Format("{0:00.0}", 123.4567);      // "123.5"
String.Format("{0:00.0}", 23.4567);       // "23.5"
String.Format("{0:00.0}", 3.4567);        // "03.5"
String.Format("{0:00.0}", -3.4567);       // "-03.5"

Thousands separator

To format double to string with use of thousands separator use zero and comma separator before an usual float formatting pattern, e.g. pattern „0,0.0“ formats the number to use thousands separators and to have one decimal place.
[C#]
String.Format("{0:0,0.0}", 12345.67);     // "12,345.7"
String.Format("{0:0,0}", 12345.67);       // "12,346"

Zero

Float numbers between zero and one can be formatted in two ways, with or without leading zero before decimal point. To format number without a leading zero use # before point. For example „#.0“ formats number to have one decimal place and zero to N digits before decimal point (e.g. „.5“ or „123.5“).
Following code shows how can be formatted a zero (of double type).
[C#]
String.Format("{0:0.0}", 0.0);            // "0.0"
String.Format("{0:0.#}", 0.0);            // "0"
String.Format("{0:#.0}", 0.0);            // ".0"
String.Format("{0:#.#}", 0.0);            // ""

Align numbers with spaces

To align float number to the right use comma „,“ option before the colon. Type comma followed by a number of spaces, e.g. „0,10:0.0“ (this can be used only in String.Format method, not indouble.ToString method). To align numbers to the left use negative number of spaces.
[C#]
String.Format("{0,10:0.0}", 123.4567);    // "     123.5"
String.Format("{0,-10:0.0}", 123.4567);   // "123.5     "
String.Format("{0,10:0.0}", -123.4567);   // "    -123.5"
String.Format("{0,-10:0.0}", -123.4567);  // "-123.5    "

Custom formatting for negative numbers and zero

If you need to use custom format for negative float numbers or zero, use semicolon separator;“ to split pattern to three sections. The first section formats positive numbers, the second section formats negative numbers and the third section formats zero. If you omit the last section, zero will be formatted using the first section.
[C#]
String.Format("{0:0.00;minus 0.00;zero}", 123.4567);   // "123.46"
String.Format("{0:0.00;minus 0.00;zero}", -123.4567);  // "minus 123.46"
String.Format("{0:0.00;minus 0.00;zero}", 0.0);        // "zero"

Some funny examples

As you could notice in the previous example, you can put any text into formatting pattern, e.g. before an usual pattern „my text 0.0“. You can even put any text between the zeroes, e.g. „0aaa.bbb0“.
[C#]
String.Format("{0:my number is 0.0}", 12.3);   // "my number is 12.3"
String.Format("{0:0aaa.bbb0}", 12.3);          // "12aaa.bbb3"


ref : http://www.csharp-examples.net/string-format-double/

String Format for Int [C#]


Integer numbers can be formatted in .NET in many ways. You can use static method String.Format or instance method int.ToString. Following examples shows how to align numbers (with spaces or zeroes), how to format negative numbers or how to do custom formatting like phone numbers.

Add zeroes before number

To add zeroes before a number, use colon separator „:“ and write as many zeroes as you want.
[C#]
String.Format("{0:00000}", 15);          // "00015"
String.Format("{0:00000}", -15);         // "-00015"

Align number to the right or left

To align number to the right, use comma „,“ followed by a number of characters. This alignment option must be before the colon separator.
[C#]
String.Format("{0,5}", 15);              // "   15"
String.Format("{0,-5}", 15);             // "15   "
String.Format("{0,5:000}", 15);          // "  015"
String.Format("{0,-5:000}", 15);         // "015  "

Different formatting for negative numbers and zero

You can have special format for negative numbers and zero. Use semicolon separator „;“ to separate formatting to two or three sections. The second section is format for negative numbers, the third section is for zero.
[C#]
String.Format("{0:#;minus #}", 15);      // "15"
String.Format("{0:#;minus #}", -15);     // "minus 15"
String.Format("{0:#;minus #;zero}", 0);  // "zero"

Custom number formatting (e.g. phone number)

Numbers can be formatted also to any custom format, e.g. like phone numbers or serial numbers.
[C#]
String.Format("{0:+### ### ### ###}", 447900123456); // "+447 900 123 456"
String.Format("{0:##-####-####}", 8958712551);       // "89-5871-2551"


ref : http://www.csharp-examples.net/string-format-int/