\

Facebook


วันอาทิตย์ที่ 20 ธันวาคม พ.ศ. 2558

แก้ HOSTS ไฟล์ เพื่อบล็อกเว็บไม่เหมาะสม

ขออธิบายความรู้ domain name เกริ่นนิดหน่อยก่อนนะครับ ในการเข้าเว็บไซด์เเต่ละครั้ง(หลังจากพิมพ์ URL แล้วกดปุ่ม Enter) เราจะวิ้งไปที่ name server หลักของเเต่ละโซนแต่ละประเทศเพื่อไปแปลงจากชื่อโดเมนเป็นเลข IP Address เพื่อให้คอมพิวเตอร์เข้าใจ เช่น google --> 203.146.98.27 

แล้วถ้าเราใช้โดเมนเเค่ในองค์กรเพียงอย่างเดียวหล่ะ ไม่จำเป็นต้องไปจดโดเมนเนมให้เสียตัง เสียเวลา เพราะเราสามารถแก้ไป host ไฟล์บนเครื่อง PC ของเราเองสำหรับจำลองชื่อโดเมนได้ตามใจ เช่น http://localhost ให้วิ่งไปที่เว็บหลักของบริษัท ซึ่งเราสามารถสร้างชื่อที่จำง่ายๆ ไม่ยาว เช่น http://test , http://account , http://HR เป็นต้น

เริ่มกันเลย เรียก RUN ขึ้นมาเเล้วพิมพ์ "notepad C:\Windows\System32\Drivers\etc\hosts"

เมื่อเปิดไฟล์ขึ้นมาจะได้หน้าตา ประมาณนี้ครับ
  
# Copyright (c) 1993-2009 Microsoft Corp.
#
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
#
# This file contains the mappings of IP addresses to host names. Each
# entry should be kept on an individual line. The IP address should
# be placed in the first column followed by the corresponding host name.
# The IP address and the host name should be separated by at least 

one
# space.
#
# Additionally, comments (such as these) may be inserted on individual
# lines or following the machine name denoted by a '#' symbol.
#
# For example:
#
#      102.54.94.97     rhino.acme.com          # source server
#       38.25.63.10     x.acme.com              # x client host

# localhost name resolution is handled within DNS itself.
# 127.0.0.1       localhost
# ::1             localhost
  
ให้ต่อท้ายบรรทัด โดยเพิ่ม ip addres ตามด้วย tab แล้วพิมพ์ชื่อ โดเมนที่ชอบลงไปเช่น

203.146.98.27 googl  --> (เป็น short link สำหรับเข้า Google เร็วๆ)

หลังจากนั้นกด save ไฟล์เเล้วไปที่หน้า Browser แล้วทดลองพิมพ์ http://googl/ แล้วจะพบว่าโดเมนนี้สามารถวิ่งตรงไปยังกูเกิ้ลได้สะบายๆ

ประยุคมาใช้ Block เว็บที่ไม่ต้องการ โดยการหลอกให้เว็บที่ไม่ต้องการวิ่งเข้า loopback ip ซึ่งไม่มีอยู่จริง ถ้าเข้าไปจะพบว่าไม่พบหน้าเว็บหรือ 404 not found สมมุติผมอยาก block เว็บ yahoo ก็เพิ่มบรรทัดนี้ลงไปที่ท้ายสุดของไฟล์

127.0.0.1    www.yahoo.com

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

วันพุธที่ 7 ตุลาคม พ.ศ. 2558

จัดระเบียบ SQL Query ให้อ่านง่ายๆสบายตา DEV ด้วย ApexSQL



สำหรับท่านที่ต้องใช้งาน MSSMS อยู่เป็นประจำน่าจะเจอปัญหาคล้ายๆกับผมคือ "เวลาแก้ store procedure จะเจอกับโค๊ดเทพที่ยุ่งเหยิง วุ่นวาย ไม่ได้ใส่ UPPER CASE บ้าง ย่อหน้าอ่านยากบ้าง" ซึ่งมันบั่นทอนกำลังให้การแก้เป็นอย่างมาก วันนี้ผมมาแนะนำ Free Plugin ที่จะทำให้โค๊ดอ่านง่ายยิ่งขึ้น ลุยเลย

ไปโหลดปลั้กอินจากหน้า https://www.apexsql.com/Download.aspx แล้วเลือกตัว ApexSQL Refactor  ซึ่งเป็น Free Tool ให้โหลดฟรีไม่คิดค่าใช้จ่าย จากนั้น Install ให้สมบูรณ์แล้ว restart MSSMS อีกครั้งหนึ่ง จะเห็นเมนูเพิ่มขึ้นมาที่มุมซ้ายบน


มีอยู่ 4 เมนูให้เลือกคือ

- Default 
- Compact
- Extended
- MSDN SQL BOL ถ้าชอบเดียวกับ doc บน MSDN ให้เลือกแบบนี้ครับ

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

มาดูตัวอย่าง ก่อนจัดระเบียบ







หลังจัดระเบียบ

วันพฤหัสบดีที่ 1 ตุลาคม พ.ศ. 2558

เทคนิคง่ายๆในการแสดงข้อมูลประเภทการเงิน การบัญชี ใน SQL SERVER


ในเรื่องเงินๆทองๆ หน่วยที่น้อยที่สุดคือ 1 สตางค์ (ทศนิยมสองตำแหน่งจะได้ 0.01) และ SQL SERVER ได้สร้างประเภทข้อมูลทางราคาไว้ให้ใช้งานง่ายๆแล้วคือ DECIMAL แต่การคำนวนจริงๆได้ข้อมูลที่ละเอียดกว่า 2 ตำแหน่งอยู่แล้ว ตัวอย่างง่ายๆก็เช่น อยากได้ค่าภาษี(6.3%) กับสินค้า 1295 บาท จะได้ 81.585 คำถามคือ 0.005 ที่เกินมาเราจะทำยังไง

ปล.ตอนรับเรทภาษีมูลค่าเพิ่มใหม่จาก 7% เป็น 6.3% ที่เริ่ม 1 ตุลานี้ เลยเขียนบทความนี้เป็นตัวอย่างซะเลย

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

ROUND() คือการปัดขึ้นถ้าเศษสุดท้ายมากกว่า 5 และปัดลงถ้าเศษน้อยกว่า 5 สามารถกำหนดความละเอียดของตำแหน่งทศนิยมได้
SELECT ROUND(81.585, 3, 2)
-- 81.585

แล้วยังกำหนดความละเอียดของหลักที่จะเริ่มปัดได้ เช่น
SELECT ROUND(81.585, 2)
-- 81.590

FLOOR() คือการปัดลงทุกกรณี
SELECT FLOOR(81.585)
-- 81

CEILING() คือการปัดขึ้นทุกกรณี
SELECT CEILING(81.585)
-- 82

อีกเทคนิคหนึ่งคือการ CAST หรือการเปลี่ยน TYPE ของตัวเลขซะเลย ซึ่งจริงๆแล้วมันคือการ ROUND() ก่อน CAST() เช่น
SELECT CAST( 0.0453 AS DECIMAL(10,2))
--0.05
*จะเห็นว่าเศษโดนปัดก่อนแปลงเป็นทศนิยม 2 หลัก

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

วันพฤหัสบดีที่ 13 สิงหาคม พ.ศ. 2558

POSTMAN สุดยอดเครื่องมือทดสอบ API



หากต้องสร้าง Web API ขึ้นมาสักตัวนึงไว้ให้ลูกค้าหรือVerdor เข้ามาติดต่อกับเราผ่านอินเตอร์เฟสแทนที่จะเข้าถึง database ของเราตรงๆ เราก็ต้องใช้API ใช่ไหมครับ ทีนี้เวลาเทสก็ต้องสร้าง Request จำลองขึ้นมาด้วยเครื่องมือสักตัว หนึ่งในเครื่องมือผมใช้แล้วบอกต่อเลยว่าเทพคือ POSTMAN

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

วิธีลงโปรแกรมก็ทั้งง่ายและฟรี โดยเปิดโครมเว็บบราวเซอร์ แล้วเข้าไปที่ https://chrome.google.com/webstore/detail/postman/fhbjgbiflinjbdggehcddcbncdddomop?utm_source=chrome-app-launcher-info-dialog



มาเรื่องความสามารถเจ๋งๆที่ต้องร้อง ว้าว!
การเก็บ History : ทุกครั้งที่เราสร้าง request ใหม่เรามารถกลับไปดู History ก่อนหน้าเพื่อเปรียบเทียบกันได้
การเก็บ Collection : หากมี Request ที่ต้องใช้งานเป็นประจำก็สามารถบันทึกลงเป็นคอเล็กชั่นเพื่อแบ่งหมวกหมู่ได้
การ Export ข้อมูล : Collection สามารถส่งออกได้เป็นรูปแบบ json เพื่อเอาส่งให้DEV คนอื่นๆ import ใช้งานต่อ

The Basic ก่อนสร้าง FORM POST เป็นก็ต้องรู้ว่า POST มายังไง

ที่ Chrome Debugger mode สามารถส่อง Xhr request เพื่อดูว่า parameter เเละ header มีรูปร่างหน้าตาอย่างไร  ซึ่งจะแสดงข้อมูลค่อนข้างละเอียดเช่น URL อะไร เป็นโพสหรือเก็ต, status code, header detail และ response ที่เกิดขึ้น ซื้อเราสามารถจำลองได้ โดย copy ส่วนของ request header ไปใส่โพสแมน

ไปที่ Network > กด F5 >  เลือก XHR 


Step การใช้งาน(อย่างกระชับ) (กระชับไปไม่รู้เรื่อง >> อ่านทดลองสร้าง POST ข่างล่าง)
1. เลือก RESTFUL  VERB คือการกำหนด method ที่ใช้ติดต่อ ไม่ว่าจะเป็น GET POST PUT DELETE
2. กำหนด Body Message คือการระบุ Key และ Value หรือจะกรอกเป็น URL Params ก็ยังได้
3. กำหนด Authorization ไม่เคยลองฟังชั่นนี้ครับ แต่ถ้าต้องการระบุตัวตนด้วย OAuth สากล ก็ควรใช้ตัวนี้

ทดลองสร้าง POST

1. เปิด application POSTMAN จาก chrome//:apps ขึ้นมาก่อน กดปุ่ม + เพื่อสร้าง connection ใหม่โดย เลือก From Method เป็น POST แล้วกรอก URL ที่เราต้องการเทส


2. กดเลือกที่เมนู Body จะแสดงตัวเลือก request header

- ถ้าเว็บคุณส่ง data จาก Form ปกติให้เลือก x-www-form-urlencoded จะมี Form ให้กรอกข้อมูลต่อ
- แต่หากต้องการสร้าง request ด้วย JSON ให้เลือก raw > JSON (application/json)


3. ช่องให้กรอก Form parameter จัดเลยครับอย่ารอช้า โดยในตัวอย่างเว็บไซด์ส่วนตัวของผมส่ง parameter ทั้งหมด 2 ตัว ตามรูปนะครับ

- ถ้าเป็น JSON ก็กรอกตาม format ซึ่ง POSTMAN เองก็ฉลาดพอที่จะเช็คความถูกต้องของ Syntax ก่อนส่งอีกด้วย

4. กด Send  จะแสดงข้อมูลขึ้งด้านล่าง เป็นอันจบครับ

5. กด Save เพื่อเก็บความทรงจำการเทสครั้งนี้ตลอดไป... ถุย เอาไว้เทสใหม่คราวหน้าจะได้ไม่เสีเวลากรอกใหม่ >> ชอบตรงนี้แหละ

6. กด History ถ้าจำไม่ได้ว่าอดีตเคยทำพลาดอะไรไว้ แล้วอยากรื้อความทรงจำ... ถุย เอาไว้ track ดู request เก่าๆนั้นแหละ เพื่อไม่ได้ save เอาไว้


7. Import/Export หมัดเด็ด เอาไว้สำหรับพกพา script ไปได้ทุกที่  เเค่เลือก Collection > Download Collection แค่นี้ก็แชร์ให้คนอื่นๆในทีมได้เเล้ว



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


วันจันทร์ที่ 6 กรกฎาคม พ.ศ. 2558

[Note] Error บน ASPX และ IIS

บทความนี้เก็บโน๊ต error ทั้งหมดที่ผมเคยเจอพร้อมวิธีแก้ น่าจะมีประโยชน์ครับถ้าเจอคล้ายๆกันและเอาไปปรับใช้กับ IIS จอมงอแง แตะนิดแตะหน่อยติดเออเรอตลอด


1. ตัวแรก Interop.MSXML2 โหลดไม่สำเร็จให้ลอง check app pool ดูว่าเป็นเวอร์ชั่นไหน ถ้ายังคงเป็น 2.0 ให้ลองเเก้เป็น 4.0 เเล้วรีสตาร์ทอีกครั้ง

Configuration Error

Description: An error occurred during the processing of a configuration file required to service this request. Please review the specific error details below and modify your configuration file appropriately.


Parser Error Message: Could not load file or assembly 'Interop.MSXML2' or one of its dependencies. This assembly is built by a runtime newer than the currently loaded runtime and cannot be loaded.



2. เวลาสร้าง table หรือ store procedure ใหม่แล้วเรียกใช้งานผ่าน ASP.NET execute store แสดง error : sql server invalid object name อาจเกิดจากการบันทึก cache ของตัง SQL Manager เองให้ลอง refresh ฐานข้อมูลก่อนจนกระทั้งเห็น Object ที่สร้าง แล้วเลือกคำสั่ง

Edit -> IntelliSense -> Refresh Local Cache  หรือ Ctrl + Shift + R

ตามรูป





3. เวลาใส่อักษรพอเศษเข้าไปก่อน POST REQUEST  เช่น $&#*(@&$*(#@&$*(#&$*(#&$*(#@&$)#(@$)#@*$)#@($*)(@

Server Error in '/' Application.

A potentially dangerous Request.Form value was detected from the client (ctl00$cpContent$txtCampaignID="$&#*(@&$*(#@&$*(#&$*(...").

Description: ASP.NET has detected data in the request that is potentially dangerous because it might include HTML markup or script. The data might represent an attempt to compromise the security of your application, such as a cross-site scripting attack. If this type of input is appropriate in your application, you can include code in a web page to explicitly allow it. For more information, see http://go.microsoft.com/fwlink/?LinkID=212874.

Exception Details: System.Web.HttpRequestValidationException: A potentially dangerous Request.Form value was detected from the client (ctl00$cpContent$txtCampaignID="$&#*(@&$*(#@&$*(#&$*(...").

Source Error:


[No relevant source lines]

Source File: c:\Users\ITspare03\AppData\Local\Temp\Temporary ASP.NET Files\root\9b6fe0e4\13708e62\App_Web_cwkso5lr.2.cs    Line: 


วิธีแก้ ให้เข้าไปเพิ่มบรรทัดนี้ใน system.web อย่าลืมตั้ง target framework เป็น 4
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
    <pages validateRequest="false" />
    <httpRuntime requestValidationMode="2.0" />
  </system.web>

วันเสาร์ที่ 2 พฤษภาคม พ.ศ. 2558

[ C# ] โปรแกรมคำนวน Keyword Density


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

เริ่มจากการรับข้อความ string เข้ามานั้น ต้องเอาเข้าฟังชั่นตัดคำก่อน ซึ่งภาษาอังกฤษนั้นถูกสร้างขึ้นมาให้ผสมไปด้วยวรรคคำทำให้ง่ายต่อการแบ่งคำเป็นส่วนๆแตกต่างจากภาษาอื่นๆเช่นภาษาไทยที่ใช้การแบ่งคำด้วยคำในพจนานุกรมซึ่งโจทย์นั้นยากกว่ามาก จัดข้องความเข้า split() ด้วยอักษร “ ”(เว้นวรรค) เลยครับงานนี้หมูๆ

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

จากสูตร (ความถี่ของคำ / จำนวนคำทั้งหมด) x 100 ก็จะได้ผลลัพท์ออกมาเป็นโปรแกรมคำนวน Keyword Density ตามโค๊ดตัวอย่างข้างล่างนี้

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace KeywordDensity
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            dataGridView.DataSource = GetResult(richTextBox.Text);
            dataGridView.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
            dataGridView.Update();
            textBox.Text = analyzeText.Count().ToString();
            textBoxMess.Text = countMess.ToString();
        }
        public string[] analyzeText;
        public int countMess = 0;
        private DataTable GetResult(string text)
        {
            string newText = prepareText(text);
            analyzeText = new string[] { };
            analyzeText = newText.Split(' ');
            double countWords = analyzeText.Count();
            List listResult = new List();

            foreach (string key in analyzeText)
            {
                if (key == " " || key == string.Empty || key.ToLower() == "a" ) continue;
                if (listResult.Where(it => it.key.Equals(key)).Any())
                {
                    
                    listResult.First(it => it.key.Equals(key)).freq++;
                    listResult.First(it => it.key.Equals(key)).percent = (listResult.First(it => it.key.Equals(key)).freq/countWords) * 100.0;
                    double a = listResult.First(it => it.key.Equals(key)).freq;
                }
                else
                {
                    listResult.Add(
                        new KeywordModel()
                        {
                            key = key,
                            freq = 1,
                            percent = (1.0 / countWords) * 100,
                        }
                        );
                }
            }
            DataTable dt = new DataTable();
            dt.Columns.Add("Keyword");
            dt.Columns.Add("Frequency");
            dt.Columns.Add("Percent");
            DataRow dr;
            foreach (var result in listResult.OrderByDescending(it => it.freq))
            {
                dr = dt.NewRow();
                dr[0] = result.key;
                dr[1] = result.freq;

                dr[2] = result.percent.ToString().Substring(0, result.percent.ToString().IndexOf('.') + 2) +"%";
                dt.Rows.Add(dr);
            }

            return dt;
        }
        private string prepareText(string originalText)
        {
            countMess = 0;
            string[] exceptWords = ("As ; as ; and ;And ; the ;The ;.; many ; much ;0;1;2;3;4;5;6;7;8;9;{;};(;);:;!;@;#;$;%;&;*;"
                                    +" you ;You ; of ;Of ; for ;For ; is ;Is ; are ;Are ; into ;Into ; it ;It ;"
                                    +" in ;In ; to ;To ; or ;Or ; if ;If ; with ;With ; that ;That ").Split(';');
            foreach (string c in exceptWords)
            {
                if (c != "")
                {
                    originalText = originalText.Replace(c, " ");
                    countMess++;
                }
            }
            return originalText;
        }

        public class KeywordModel
        {
            public string key { get; set; }
            public int freq { get; set; }
            public double percent { get; set; }
        }
    }
}

จากตัวอย่าง Windows Application ประกาศตัวแปร exceptWords เพื่อจัดเป็น array ของคำที่ต้องการตัดทิ้ง อย่าลืมแก้ไขกันก่อนด้วยถ้าอยากเพิ่มหรือลบคำใดเข้าไป

ปรับปรุงโค๊ดยังไง
1 เพิ่มส่วนของคำที่ไม่รวมเข้ากับการคำนวนเช่น  the, and, or
2 ปรับปรุงการ search คำแบบอื่นที่ไม่ใช่ for loop

วันจันทร์ที่ 20 เมษายน พ.ศ. 2558

วิธีแก้ Couldn't Mount File

สำหรับไฟล์ประเภท iso บน Windows 8.1 สามารถ mount หรือจำลอง disk ตัวนั้นได้เป็นไดฟ์ตัวใหม่ ทำให้ใช้งานไฟล์ข้างในได้โดยไม่ต้องเขียนลงแผ่นซีดีแบบเดิมๆ แต่ถ้าใครเจอปัญหาเดียวกันนี้


Sorry, there was a problem mounting the file.









แก้ไขง่ายๆด้วยการ copy ไฟล์ไปลงไดเรกเทอรี่อื่น เพียงเท่านี้ก็ใช้งานได้ตามปกติ เอิ้ก!! เมื่อวานผมก็นั่งงงตั้งนานสองนานว่าไฟล์เสียหรือเปล่า ทดลองเขียนลง USB ก็ปกติดี สามารถบูทได้ตามปกติ เพียงเเค่ไม่สามารถ mount ได้แต่พอ copy ไฟล์ไปไว้ที่อื่นเท่านั้นแหละดันใช้ได้ตามปกติ

วันจันทร์ที่ 23 มีนาคม พ.ศ. 2558

[Android] Stream เสียงจาก PC บน Network ด้วย SoundWire



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


App ที่ว่านี้มีชื่อว่า SoundWire ครับผม ซึ่งวันนี้ ผมจะมารีวิวการใช้งานให้เพื่อนๆทดลองเล่นแอปตัวนี้ดู การใช้งานก็ไม่อยากครับ ท่านต้องมี app บนอุปกรณ์ Android ชื่อว่า SoundWire (free tial) สามารถค้นหาชื่อนี้จาก Google Play Store ได้เลยครับ ส่วนทางด้าน PC ก็ไปตาม link ด้านล่างนี้เลยครับ

Android Version : https://play.google.com/store/apps/details?id=com.georgie.SoundWireFree&hl=th
PC Version :  http://soundwire-server.en.uptodown.com/

ต่อไปคือส่วนที่สำคัญที่สุดนั้นคือต้องเชื่อมต่อ "เน็ตเวิร์ค" ตัวเดียวกัน เพื่อให้มือถือมองเห็น IP Address ของฝั่งคอมพิวเตอร์ เพราะตัวพีซีเองจะทำตัวเหมือนเป็น audio streaming ซึ่งอุปกรณ์ที่เชื่อมต่อเข้ากับไอพีนี้จะสามารถฟังเสียงได้นั้นเอง ซึ่งถ้าท่านไม่มี router เป็นของตัวเองแนะนำให้ต่อเข้ากับ TRUE Wifi ได้เลยครับ


ตัวโปรแกรมไม่ได้ซับซ้อนอะไรครับ เพียงเเค่รัน exe เเล้ว จะได้ IP ปัจจุบันมา ซึ่งต้องนำไอพีนี้ไปกรอกใน app android อีกทีนึง นอกจากนี้ก็มี option 
- input select : เลือก input 
- status : สถานะ ถ้า connected เเสดงว่าเชื่อต่อเเล้ว
- Audio output : ระดับ volyume
- Record flie : บันทึกไฟล์เสียง 

ทางฝั่ง Androd ให้กรอกไอพี เเล้วกดที่ logo ของแอป ที่เหลือก็เเค่เพียงเปิดลำโพงดังๆตามใจชอบเลยครับ ซึ่งข้อดีของแอปนี้คือ




1. สะดวกในการหาลำโพงเสริมความดังด้วยมือถือ
2. สามารถต่อมือถือได้หลายๆตัว เพียงแค่มีแอปตัวนี้
3. ใช้งานง่าย เเค่มี network

ข้อเสีย
1. เว่อร์ชั่น free มี limit ในการใช้งาน
2. เสียง delay อยู่นิดๆ ตามความเเรงสัญญาณ
3. ถ้า network สัญญาณอ่อนมากๆเช่นใช้งาน true wifi ตอนเย็นๆ เสียงจะ delay และขาดตอนมากๆ ควรมี router ส่วนตัวอยู่เเล้ว

สรุป ใช้งานง่ายครับ เอาไว้เเก้ขัดกรณีลำโพงเสีย รอซ่อม ให้ 9/10

วันอังคารที่ 24 กุมภาพันธ์ พ.ศ. 2558

[PHP] วิธีจับ Notice มาเป็น Exception ใน TryCatch


ในภาษาพีเฮชพี Notice กับ Warning ไม่ถือเป็น runtime error ครับ ทำให้เวลาเราครอบด้วย try catch มันก็จะไม่เด้งไปที่ส่วนของ Exception  ex เเต่จะขึ้นข้อความขึ้นมาเเจ้งเตือนแทน ซึ่งส่วนใหญ่ก็คุ้นกับการตั้งค่า error_report() ให้ซ่อนข้อความเหล่านั้นไป

เเต่ถ้าอยากตั้งกฎขึ้นมาใหม่ว่า Notice  ก็ถือเป็น Exception ตัวหนึ่ง(เช่น Undefined index เป็นต้น) ก็ต้องจัดการด้วยฟังชั่น set_error_handler() เองครับ

ซึ่งบทความนี้ ผมจะแนะนำการจัดการ error ด้วยฟังชั่นเราเอง เช่นผมจะนับว่าการไม่เจออินเด็กใน array ถึงว่าผิดพลาด ก็ให้สร้างฟังชั่นนี้ขึ้นมาครับ

function errorHandlerCatchUndefinedIndex($errno, $errstr, $errfile, $errline ) {
    // In case Undefined index
    if (substr($errstr, 0, 16) == 'Undefined index:') {
     throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
   } 
    return false;
}

เเล้วเรียกฟังชั่นด้วยคำสั่งนี้ ก่อนเข้า try

   // Set Notice return Error
   set_error_handler("errorHandlerCatchUndefinedIndex");

หลับจบ catch หรือ finally ใส่คำสั่งนี้เพื่อกลับคืนสู่การตั้งค่า error ปกติของระบบ

   // Restore Error
   restore_error_handler();

หน้าตาโค๊ดจะออกมาประมาณนี้

 set_error_handler("errorHandlerCatchUndefinedIndex");
try{
//do something!!
}catch(Exception $e){
restore_error_handler();
}
restore_error_handler();


อ้างอิง http://stackoverflow.com/questions/3261051/how-to-catch-an-undefined-index-e-notice-error-in-simpletest

[XAMPP] เร่งความเร็ว Apache ด้วย mod_log_config


 เคยไหมครับเวลาใช้งาน XAMPP เป็นเซิฟเว่อร์จำลอง แล้วเเต่ละ request ที่ส่งไปใช้เวลานานเหลือเกิน ตั้ง timeout ไว้ 30 วินาที บางครั้งยังไม่พอ แล้วหลังจาก Return ข้อผิดพลาดกลับดันเป็นแค่ Notice ธรรมดา จนบางคนแก้ปัญหาด้วยการ ประกาศปิด Notice กับ Error ไว้ที่หัวไฟล์ซะเลย

แต่พอระบบใหญ่ขึ้นมา เจอโจทย์แบบว่า "Notice เป็นแบบไหนต้องแก้ให้ได้ทั้งหมด" ซึ่งส่วนใหญ่มันจะเกิดจากสาเหตุที่ object ไม่มีอยู่จริง, อินเด็กที่เรียกไม่มีอยู่ หรือ Loop ไม่มีสมาชิกอยู่เลย(count=0)  วนๆกันอยู่ประมาณนี้แหละครับ

เวลาฝั่ง Server เจอข้อผิดพลาด จะทำการเก็บล็อกเอาไว้ ซึ่งวิธีที่จะเร่งความเร็วเพิ่มขึ้นวันนี้ก็คือการ เพิ่มความเร็วในการบันทึก Log นั่นเอง โดยใช้โมดูลที่มีชื่อว่า mod_log_config โดยหากใช้ XAMPP เวอชั่น WINDOWS ก็ทำตามนี้ครับ เปิด "httpd.conf" ขึ้นมาแล้วเพิ่มบรรทัดข้างล่างเข้าไป

<IfModule mod_log_config.c>
  LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"**%T/%D**" combined
  CustomLog logs/access.log combined
  <IfModule mod_deflate.c>
    DeflateFilterNote Input instream
    DeflateFilterNote Output outstream
    DeflateFilterNote Ratio ratio
    LogFormat '"%r" %{outstream}n/%{instream}n (%{ratio}n%%)' deflate
    CustomLog logs/deflate.log deflate
  </IfModule>
</IfModule>


มันคือการเพิ่ม format ของ Log นั่นเอง ซึ่ง %T คือเวลาที่ใช้ในหน่วย millisec เเทนที่จะเป็นแค่ sec ซึ่งจะออกมาหน้าตาประมาณนี้

LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"**%T/%D**" combined

that is logging the time spent to serve the request but in microseconds (10-6) instead of seconds.(อ้างอิง)
 ที่มา: http://www.ducea.com/2008/02/06/apache-logs-how-long-does-it-take-to-serve-a-request/
ปล. ใช้ได้กับ apache version 2.0.x ขึ้นไป

ผมยังไม่ได้เทส จริงจังนะครับ ว่าไวขึ้นจริงๆไหม (ดันมาเจอบทความตอนโปรเจกค์ใกล้จบ) ใครเทสเเล้ว work หรือไวขึ้นจริงๆ post comment ไว้ด้วยนะครับ

วันจันทร์ที่ 23 กุมภาพันธ์ พ.ศ. 2558

PHP Simple HTML DOM Parser API

รวบรวม API ของ Simple HTML DOM เอาไว้ครับ สำหรับ link เต็มๆของหน้าหลักอยู่ที่นี้ คลาสตัวนี้เมื่อโหลดลงมาใช้มีประโยชน์ที่แปลงมาร์คอัพประเภท html ให้เป็น object DOM ทำง่ายต่อการค้นหา node ที่ต้องการไปใช้ต่อ บลาๆๆ ขี้เกียจอธิบาย จริงๆก็รู้กันอยู่เเล้ว แต่อยากรวบรวม ฟังชั่นที่ใช้บ่อยๆ+จำเป็น เอาไว้กันลืมครับ


อันนี้ Method >> ที่ผมใช้บ่อยๆ childNodes() , parentNode() เป็นต้นครับ การลบ element ของ DOM ทำไม่ได้ ต้องเลี่ยงมาใช้ removeAttribute() แทน เช่นลบ link ใน <iframe> เป็นต้น


Method Mapping
array
$e->getAllAttributes ()
array
$e->attr
string
$e->getAttribute ( $name )
string
$e->attribute
void
$e->setAttribute ( $name, $value )
void
$value = $e->attribute
bool
$e->hasAttribute ( $name )
bool
isset($e->attribute)
void
$e->removeAttribute ( $name )
void
$e->attribute = null
element
$e->getElementById ( $id )
mixed
$e->find ( "#$id", 0 )
mixed
$e->getElementsById ( $id [,$index] )
mixed
$e->find ( "#$id" [, int $index] )
element
$e->getElementByTagName ($name )
mixed
$e->find ( $name, 0 )
mixed
$e->getElementsByTagName ( $name [, $index] )
mixed
$e->find ( $name [, int $index] )
element
$e->parentNode ()
element
$e->parent ()
mixed
$e->childNodes ( [$index] )
mixed
$e->children ( [int $index] )
element
$e->firstChild ()
element
$e->first_child ()
element
$e->lastChild ()
element
$e->last_child ()
element
$e->nextSibling ()
element
$e->next_sibling ()
element
$e->previousSibling ()
element
$e->prev_sibling ()

ส่วนอันนี้ เป็น element ท่องไว้เลย ยังไงก็ได้ใช้



May be like this posts