Tag Archive array

JoGet: Bean Shell Create Json

วิธีดีที่สุดในการให้ข้อมูลจำนวนมากให้ javascript คือรูปแบบ json ไม่เว้นแม้แต่ใน JoGet เพราะถึงแม้จะสามารถดึงข้อมูลจาก input หรือ grid ได้ แต่มันจะถูกบันทึกลง database ไปด้วยแถมดูรก

วิธีที่ดีอีกวิธีคือให้ beanshell ใน section ดึงข้อมูลจาก query แล้วแสดงออกมาใน input ตัวเดียว[code language=”java” title=”Bean Shell Create Json”]import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.joget.apps.app.service.AppUtil;
import org.joget.apps.form.model.Element;
import org.joget.apps.form.model.FormData;
import org.joget.apps.form.model.FormRow;
import org.joget.apps.form.model.FormRowSet;
import org.joget.apps.form.service.FormUtil;
import org.joget.commons.util.LogUtil;
import org.json.simple.JSONObject;

public FormRowSet load(Element element, String username, FormData formData) {

FormRowSet rows = new FormRowSet();

Connection con = null;
try {
DataSource ds = (DataSource) AppUtil.getApplicationContext().getBean("setupDataSource");
con = ds.getConnection();

sql = "SELECT appId, appVersion, name FROM jwdb.app_app WHERE published = 1;";
//LogUtil.info("Bean Shell Create Json", "sql = " + sql);

if (!con.isClosed()) {
PreparedStatement stmt = con.prepareStatement(sql);
ResultSet rs = stmt.executeQuery();

/* create json */
JSONObject json = new JSONObject();
while (rs.next()) {
JSONObject item = new JSONObject();

item.put("appVersion", rs.getObject("appVersion"));
item.put("name", rs.getObject("name"));

json.put(rs.getObject("appId"), item);
}

/* add json to input */
FormRow row = new FormRow();
rows.add(row);
row.put("json", json.toString());
}

} catch (Exception e) {
LogUtil.error(getClassName(), e, "Bean Shell Create Json");
} finally {
try {
if (con != null) {
con.close();
}
} catch (SQLException e) {}
}

return rows;
}

return load(element, primaryKey, formData);[/code]

ตัวอย่างฟอร์ม[code language=”javascript” title=”Bean Shell Create Json”]{
"className": "org.joget.apps.form.model.Form",
"properties": {
"noPermissionMessage": "",
"loadBinder": {
"className": "org.joget.apps.form.lib.WorkflowFormBinder",
"properties": {}
},
"name": "Bean Shell Create Json",
"description": "",
"postProcessorRunOn": "both",
"permission": {
"className": "",
"properties": {}
},
"id": "BeanShellCreateJson",
"postProcessor": {
"className": "",
"properties": {}
},
"storeBinder": {
"className": "org.joget.apps.form.lib.WorkflowFormBinder",
"properties": {}
},
"tableName": "prototypes"
},
"elements": [
{
"elements": [
{
"elements": [
{
"className": "org.joget.apps.form.lib.TextArea",
"properties": {
"readonly": "",
"validator": {
"className": "",
"properties": {}
},
"workflowVariable": "",
"id": "json",
"label": "JSON",
"placeholder": "",
"rows": "10",
"value": "",
"cols": "100",
"readonlyLabel": ""
}
}
],
"className": "org.joget.apps.form.model.Column",
"properties": {
"width": "100%"
}
}
],
"className": "org.joget.apps.form.model.Section",
"properties": {
"readonly": "",
"loadBinder": {
"className": "org.joget.apps.form.lib.BeanShellFormBinder",
"properties": {
"useAjax": "",
"cacheIdlePause": "120",
"cacheInterval": "",
"script": "import java.sql.Connection;\nimport java.sql.PreparedStatement;\nimport java.sql.ResultSet;\nimport java.sql.SQLException;\nimport javax.sql.DataSource;\nimport org.joget.apps.app.service.AppUtil;\nimport org.joget.apps.form.model.Element;\nimport org.joget.apps.form.model.FormData;\nimport org.joget.apps.form.model.FormRow;\nimport org.joget.apps.form.model.FormRowSet;\nimport org.joget.apps.form.service.FormUtil;\nimport org.joget.commons.util.LogUtil;\nimport org.json.simple.JSONObject;\n\npublic FormRowSet load(Element element, String username, FormData formData) {\n\n FormRowSet rows = new FormRowSet();\n\n Connection con = null;\n try {\n DataSource ds = (DataSource) AppUtil.getApplicationContext().getBean(\"setupDataSource\");\n con = ds.getConnection();\n\n sql = \"SELECT appId, appVersion, name FROM jwdb.app_app WHERE published = 1;\";\n //LogUtil.info(\"Bean Shell Create Json\", \"sql = \" + sql);\n\n if (!con.isClosed()) {\n PreparedStatement stmt = con.prepareStatement(sql);\n ResultSet rs = stmt.executeQuery();\n\n /* create json */\n JSONObject json = new JSONObject();\n while (rs.next()) {\n JSONObject item = new JSONObject();\n\n item.put(\"appVersion\", rs.getObject(\"appVersion\"));\n item.put(\"name\", rs.getObject(\"name\"));\n\n json.put(rs.getObject(\"appId\"), item);\n }\n\n /* add json to input */\n FormRow row = new FormRow();\n rows.add(row);\n row.put(\"json\", json.toString());\n }\n\n } catch (Exception e) {\n LogUtil.error(getClassName(), e, \"Bean Shell Create Json\");\n } finally {\n try {\n if (con != null) {\n con.close();\n }\n } catch (SQLException e) {}\n }\n\n return rows;\n}\n\nreturn load(element, primaryKey, formData);"
}
},
"permissionReadonly": "",
"permission": {
"className": "",
"properties": {}
},
"comment": "",
"id": "section1",
"label": "Bean Shell Create Json",
"storeBinder": {
"className": "",
"properties": {}
},
"readonlyLabel": ""
}
}
]
}[/code]

JAVA: Create Json

การสร้าง json ใน java ทั้งแบบ array [“aaa”, “bbb”, “ccc”] และ object {“aaa”:”bbb”, “ccc”:”ddd”, “eee”:”fff”} ทำได้ง่ายๆ

สร้าง json array[code language=”java” title=”json array”]import org.json.simple.JSONArray;

JSONArray json = new JSONArray();
while (rs.next()) {
JSONObject item = new JSONArray();

item.add(rs.getObject("appId"));
item.add(rs.getObject("appVersion"));
item.add(rs.getObject("name"));

json.add(item);
}[/code]

รวมร่าง[code language=”java” title=”add json array”]json.add( { JSONArray ที่ต้องการรวม } );[/code]

สร้าง json object[code language=”java” title=”json object”]import org.json.simple.JSONObject;

JSONObject json = new JSONObject();
while (rs.next()) {
JSONObject item = new JSONObject();

item.put("appVersion", rs.getObject("appVersion"));
item.put("name", rs.getObject("name"));

json.put(rs.getObject("appId"), item);
}[/code]

รวมร่าง[code language=”java” title=”json to string”]json.put( {index ที่ต้องการ}, { JSONArray ที่ต้องการรวม } );[/code]

แปลงเป็น string เพื่อใช้อย่างอื่น[code language=”java” title=”json to string”]json.toString()[/code]

อ่านเพิ่มเติม JoGet: Bean Shell Create Json

MySQL: return json format

mysql ก็ support json เพราะว่าเดี๋ยวนี้อะไรๆ ก็แลกเปลี่ยนข้อมูลกันโดยใช้ json ถ้าสามารถ query จาก mysql ให้ result ออกมาเป็น json เลย ก็สะดวกที่จะไม่ต้องใช้ java หรือ beanshell ใน joget แปลงผลลัพธ์ให้ยุ่งยาก แค่มี input ซักตัวก็สามารถนำมันไปใช้ได้เลย

เริ่มจากการที่เขียน query ตามปกติเพื่อเลือกข้อมูลที่ต้องการ เช่น[code langage=”sql” title=”select provinces”]SELECT
*
FROM
snippets.province
ORDER BY PROVINCE_NAME ASC;[/code]จะเห็นว่ามี column PROVINCE_ID, PROVINCE_CODE, PROVINCE_NAME และ GEO_ID ทีนี้จะแปลง ให้เป็นรูปแบบ json array โดยใช้ JSON_OBJECT วิธีการใช้คือ[code language=”sql” title=”function JSON_OBJECT”]SELECT JSON_OBJECT(‘name1’, value1, ‘name2’, value2, ‘name3’, value3);[/code]คือ[code language=”sql” title=”function JSON_OBJECT example”]SELECT
JSON_OBJECT(‘PROVINCE_ID’,
PROVINCE_ID,
‘PROVINCE_CODE’,
PROVINCE_CODE,
‘PROVINCE_NAME’,
PROVINCE_NAME,
‘GEO_ID’,
GEO_ID) AS json
FROM
snippets.province
ORDER BY PROVINCE_NAME ASC;[/code]ค่าค่อยดูเป็น json ขึ้นมาหน่อย แต่มันยังอยู่คนละแถว ไม่เป็นไรมีตัวช่วย[code language=”sql” title=”mysql query to json”]SELECT
CONCAT(‘[‘,
GROUP_CONCAT(JSON_OBJECT(‘PROVINCE_ID’,
PROVINCE_ID,
‘PROVINCE_CODE’,
PROVINCE_CODE,
‘PROVINCE_NAME’,
PROVINCE_NAME,
‘GEO_ID’,
GEO_ID)),
‘]’) AS json
FROM
snippets.province
ORDER BY PROVINCE_NAME ASC;[/code]

แค่นี้ก็ได้ result เป็น json สมใจ อ่านตัวอย่างการใช้ได้ที่ javascript: string to JSON.parse()

MySQL: select ข้อมูลจาก json array

Mysql การดึงข้อมูลจากรูปแบบ json ที่เก็บเป็น array ไว้ จะเขียน query ซับซ้อนกว่าปกตินิดหนึ่งเพราะว่าต้องมีการดึงข้อมูลโดยทราบจำนวนแถว เช่น จากข้อมูล[code language=”sql” title=””]CREATE TABLE `app_fd_books` (
`id` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`dateCreated` datetime DEFAULT NULL,
`dateModified` datetime DEFAULT NULL,
`c_books` longtext COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

INSERT INTO `app_fd_books` (`id`,`dateCreated`,`dateModified`,`c_books`) VALUES (‘b04469bd-ac1430f1-12bd2000-a4f7da3a’,’2018-03-03 22:54:56′,’2018-03-03 22:54:56′,'[{\n \"title\": \"สูญสิ้นความเป็นคน\",\n \"author\": \"ดะไซ โอซามุ\",\n \"publisher\": \"JLIT\"\n }, {\n \"title\": \"ถอดรหัสรักออนไลน์\",\n \"author\": \"Aziz Ansari\",\n \"publisher\": \"openworlds\"\n },\n {\n \"title\": \"เพลงรัตติกาลในอินเดีย\",\n \"author\": \"Antonio Tabucchi\",\n \"publisher\": \"อ่านอิตาลี\"\n },\n {\n \"title\": \"อันเดอร์กราวด์\",\n \"author\": \"ผู้เขียน: ฮารูกิ มูราคามิ\",\n \"publisher\": \"กำมะหยี่\"\n },\n {\n \"title\": \"ร้านหนังสือเลขที่ 84 ถนนแชริงครอสส์\",\n \"author\": \"Helene Hanff\",\n \"publisher\": \"Bookmoby Press\"\n },\n {\n \"title\": \"ปรัชญาในภาพยนตร์\",\n \"author\": \"ผู้เขียน: สิตางค์ เจริญวงศ์ และ ฐานชน จันทร์เรือง\",\n \"publisher\": \"ปล่อยสำนักพิมพ์\"\n },\n {\n \"title\": \"ผู้มาเยือนหลังเที่ยงคืน\",\n \"author\": \"แพทริก เนส\",\n \"publisher\": \"เวิร์ดส์วอนเดอร์\"\n },\n {\n \"title\": \"เข้าป่าหาชีวิต\",\n \"author\": \"จอน คราคาวเออร์\",\n \"publisher\": \"มูลนิธิหนังสือเพื่อสังคม\"\n },\n {\n \"title\": \"ไกลกว่ารั้วบ้านของเรา\",\n \"author\": \"โรสนี นูรฟารีดา\",\n \"publisher\": \"ผจญภัย\"\n },\n {\n \"title\": \"สัจนิยมมหัศจรรย์\",\n \"author\": \"ชูศักดิ์ ภัทรกุลวณิชย์\",\n \"publisher\": \"อ่าน\"\n },\n {\n \"title\": \"เข้าป่าหาชีวิต\",\n \"author\": \"จอน คราคาวเออร์\",\n \"publisher\": \"มูลนิธิหนังสือเพื่อสังคม\"\n },\n {\n \"title\": \"ความลับ 5 ข้อที่คุณต้องค้นให้พบก่อนตาย\",\n \"author\": \"จอห์น อิซโซ\",\n \"publisher\": \"โอ้มายก้อด\"\n },\n {\n \"title\": \"ฝนบางหยด กลายเป็นผีเสื้อ\",\n \"author\": \"ลัดดา สงกระสินธิ์\",\n \"publisher\": \"สมมติ\"\n },\n {\n \"title\": \"Open Diary\",\n \"author\": \"วรพจน์ พันธุ์พงศ์\",\n \"publisher\": \"บางลำพู\"\n },\n {\n \"title\": \"A Gothic Soul\",\n \"author\": \"Jiří Karásek ze Lvovic\",\n \"publisher\": \"Twisted Spoon\"\n },\n {\n \"title\": \"ไกลกว่ารั้วบ้านของเรา\",\n \"author\": \"โรสนี นูรฟารีดา\",\n \"publisher\": \"ผจญภัย\"\n },\n {\n \"title\": \"ประวัติศาสตร์นับศูนย์: สู่การสูญพันธุ์ครั้งที่ 6\",\n \"author\": \"เอลิซาเบธ โคลเบิร์ต\",\n \"publisher\": \"openworlds\"\n },\n {\n \"title\": \"FUTURE : ปัญญาอนาคต\",\n \"author\": \"ภิญโญ ไตรสุริยธรรมา\",\n \"publisher\": \"openbooks\"\n }\n]’);[/code]c_books มีจำนวนข้อมูลที่เก็บเอาไว้ 18 รายการ

เพื่อความสดวกการเขียน query จะใช้วิธีสร้างตารางเก็บ index ไว้ให้เกาะโดย เราจะสร้างตาราง integers ที่เก็บจำนวนเต็มตั้งแต่ 0 ถึง n ( function JSON_EXTRACT เริ่มจาก index 0 ) เอาไว้ให้ใช้ง่ายๆ เช่น[code language=”sql” title=”integers”]CREATE TABLE `integers` (
`row_number` int(4) NOT NULL,
PRIMARY KEY (`row_number`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO integers (row_number) VALUES (‘0’) , (‘1’) , (‘2’) , (‘3’) , (‘4’) , (‘5’) , (‘6’) , (‘7’) , (‘8’) , (‘9′) , (’10’) , (’11’) , (’12’) , (’13’) , (’14’) , (’15’) , (’16’) , (’17’) , (’18’) , (’19’) , (’20’) , (’21’) , (’22’) , (’23’) , (’24’) , (’25’) , (’26’) , (’27’) , (’28’) , (’29’) , (’30’) , (’31’) , (’32’) , (’33’) , (’34’) , (’35’) , (’36’) , (’37’) , (’38’) , (’39’) , (’40’) , (’41’) , (’42’) , (’43’) , (’44’) , (’45’) , (’46’) , (’47’) , (’48’) , (’49’) , (’50’) , (’51’) , (’52’) , (’53’) , (’54’) , (’55’) , (’56’) , (’57’) , (’58’) , (’59’) , (’60’) , (’61’) , (’62’) , (’63’) , (’64’) , (’65’) , (’66’) , (’67’) , (’68’) , (’69’) , (’70’) , (’71’) , (’72’) , (’73’) , (’74’) , (’75’) , (’76’) , (’77’) , (’78’) , (’79’) , (’80’) , (’81’) , (’82’) , (’83’) , (’84’) , (’85’) , (’86’) , (’87’) , (’88’) , (’89’) , (’90’) , (’91’) , (’92’) , (’93’) , (’94’) , (’95’) , (’96’) , (’97’) , (’98’) , (’99’) , (‘100’)[/code]

ส่วนเรื่องจะดึงข้อมูลถึงอันดับที่เท่าไหร่ ถ้าไม่บันทึกไว้ที่คอลัมน์อื่น ก็ทำได้โดยการเขียนเงื่อนไขเช่น ข้อมูลเกี่ยวกับหนังสือทุกเล่ม ต้องมีชื่อเรื่อง (title) ก็จะเขียนประมาณ[code language=”sql” title=”exit condition”]AND (SELECT
TRIM(BOTH ‘"’ FROM JSON_EXTRACT(datas.c_books,
CONCAT(‘$[‘, row_number, ‘].title’)))
FROM
app_fd_books
WHERE
id = ‘b04469bd-ac1430f1-12bd2000-a4f7da3a’) IS NOT NULL[/code]

ตัวอย่าง query ที่เขียนเสร็จแล้ว เช่น[code language=”sql” title=”MySQL data form JSON Array with condition”]SELECT
row_number,
TRIM(BOTH ‘"’ FROM JSON_EXTRACT(datas.c_books,
CONCAT(‘$[‘, row_number, ‘].title’))) AS title,
TRIM(BOTH ‘"’ FROM JSON_EXTRACT(datas.c_books,
CONCAT(‘$[‘, row_number, ‘].author’))) AS author,
TRIM(BOTH ‘"’ FROM JSON_EXTRACT(datas.c_books,
CONCAT(‘$[‘, row_number, ‘].publisher’))) AS publisher
FROM
app_fd_books AS datas,
(SELECT
row_number AS row_number
FROM
integers) AS length
WHERE
datas.id = ‘b04469bd-ac1430f1-12bd2000-a4f7da3a’
AND (SELECT
TRIM(BOTH ‘"’ FROM JSON_EXTRACT(datas.c_books,
CONCAT(‘$[‘, row_number, ‘].title’)))
FROM
app_fd_books
WHERE
id = ‘b04469bd-ac1430f1-12bd2000-a4f7da3a’) IS NOT NULL
ORDER BY row_number;[/code]

แต่เมื่อใช้ไปนานๆ เจอวิธีที่เขียนได้ง่ายกว่าเดิมคือใช้ JSON_LENGTH ก็จะได้รูปแบบ[code language=”sql” title=”MySQL data form JSON Array with length”]SELECT
row_number,
TRIM(BOTH ‘"’ FROM JSON_EXTRACT(datas.c_books,
CONCAT(‘$[‘, row_number, ‘].title’))) AS title,
TRIM(BOTH ‘"’ FROM JSON_EXTRACT(datas.c_books,
CONCAT(‘$[‘, row_number, ‘].author’))) AS author,
TRIM(BOTH ‘"’ FROM JSON_EXTRACT(datas.c_books,
CONCAT(‘$[‘, row_number, ‘].publisher’))) AS publisher
FROM
integers AS i,
app_fd_books AS datas
WHERE
datas.id = ‘b04469bd-ac1430f1-12bd2000-a4f7da3a’
AND i.row_number < JSON_LENGTH(datas.c_books)
ORDER BY row_number;[/code]มันง่าย และสั้นกว่าเยอะเลยพิชญ์

PHP: json_encode ไม่มีผลลัพธ์

เจอว่า json_encode มันไม่ return ผลลัพธ์ ออกมาเลยในหน้าเดียวกัน แต่ต่างกันที่ product id ลอง print_r / var_dump ตัว array ที่เข้าไปใน function ก็ปกติดี ไม่ได้มากมาย หรือมีเครื่องหมายพิเศษอะไร ลอง debug ดูถึงเจอว่าถ้าใช้ function json_last_error() มันจะ return เลข 7 กลับมาในหน้าที่มีปัญหา ลองค้นดูรหัส 7 คือ infinity number ลอง unset ตัว key ที่เป็น float(-INF) ดูก็กลับเป็นปกติจริงๆ

รหัสต่างๆ คือ

JSON error codes
Code Constant Meaning Availability
0 JSON_ERROR_NONE No error has occurred  
1 JSON_ERROR_DEPTH The maximum stack depth has been exceeded  
2 JSON_ERROR_STATE_MISMATCH Invalid or malformed JSON  
3 JSON_ERROR_CTRL_CHAR Control character error, possibly incorrectly encoded  
4 JSON_ERROR_SYNTAX Syntax error  
5 JSON_ERROR_UTF8 Malformed UTF-8 characters, possibly incorrectly encoded PHP 5.3.3
6 JSON_ERROR_RECURSION One or more recursive references in the value to be encoded PHP 5.5.0
7 JSON_ERROR_INF_OR_NAN One or moreNANor INFvalues in the value to be encoded PHP 5.5.0
8 JSON_ERROR_UNSUPPORTED_TYPE A value of a type that cannot be encoded was given PHP 5.5.0
9 JSON_ERROR_INVALID_PROPERTY_NAME A property name that cannot be encoded was given PHP 7.0.0
10 JSON_ERROR_UTF16 Malformed UTF-16 characters, possibly incorrectly encoded PHP 7.0.0

[code language=”php” title=”php_json_encode.php”]
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<title>PHP: json_encode error</title>
<meta content="Pitt Phunsanit" name="author" />
</head>
<body>
<div class="container">
<?php
$datas = [
‘ininfity’ => -9e1000,
‘title’ => ‘title’,
];
?>
<div class="row"><label class="col-md-2" for="">Datas Arrya:</label><textarea class="col-md-10" cols="100" rows="6"><?=var_dump($datas); ?></textarea></div>
<div class="row"><label class="col-md-2" for="">Json Datas:</label><textarea class="col-md-10" cols="100" rows="6"><?=json_encode($datas); ?></textarea></div>
<div class="row">
<label class="col-md-2" for="">Json Error:</label>
<div class="col-md-10"><?=json_last_error(); ?></div>
</div>
<table class="table table-striped">
<caption><strong>JSON error codes</strong></caption>
<thead>
<tr>
<th>Code</th>
<th>Constant</th>
<th>Meaning</th>
<th>Availability</th>
</tr>
</thead>
<tbody class="tbody">
<tr>
<td><strong><code><?=JSON_ERROR_NONE; ?></code></strong></td>
<td><strong><code>JSON_ERROR_NONE</code></strong></td>
<td>No error has occurred</td>
<td class="empty">&nbsp;</td>
</tr>
<tr>
<td><strong><code><?=JSON_ERROR_DEPTH; ?></code></strong></td>
<td><strong><code>JSON_ERROR_DEPTH</code></strong></td>
<td>The maximum stack depth has been exceeded</td>
<td class="empty">&nbsp;</td>
</tr>
<tr>
<td><strong><code><?=JSON_ERROR_STATE_MISMATCH; ?></code></strong></td>
<td><strong><code>JSON_ERROR_STATE_MISMATCH</code></strong></td>
<td>Invalid or malformed JSON</td>
<td class="empty">&nbsp;</td>
</tr>
<tr>
<td><strong><code><?=JSON_ERROR_CTRL_CHAR; ?></code></strong></td>
<td><strong><code>JSON_ERROR_CTRL_CHAR</code></strong></td>
<td>Control character error, possibly incorrectly encoded</td>
<td class="empty">&nbsp;</td>
</tr>
<tr>
<td><strong><code><?=JSON_ERROR_SYNTAX; ?></code></strong></td>
<td><strong><code>JSON_ERROR_SYNTAX</code></strong></td>
<td>Syntax error</td>
<td class="empty">&nbsp;</td>
</tr>
<tr>
<td><strong><code><?=JSON_ERROR_UTF8; ?></code></strong></td>
<td><strong><code>JSON_ERROR_UTF8</code></strong></td>
<td>Malformed UTF-8 characters, possibly incorrectly encoded</td>
<td>PHP 5.3.3</td>
</tr>
<tr>
<td><strong><code><?=JSON_ERROR_RECURSION; ?></code></strong></td>
<td><strong><code>JSON_ERROR_RECURSION</code></strong></td>
<td>One or more recursive references in the value to be encoded</td>
<td>PHP 5.5.0</td>
</tr>
<tr>
<td><strong><code><?=JSON_ERROR_INF_OR_NAN; ?></code></strong></td>
<td><strong><code>JSON_ERROR_INF_OR_NAN</code></strong></td>
<td>
One or more
<a class="link" href="http://php.net/manual/de/language.types.float.php#language.types.float.nan" target="_blank"><strong><code>NAN</code></strong></a>
or <a class="link" href="http://php.net/manual/de/function.is-infinite.php" target="_blank"><strong><code>INF</code></strong></a>
values in the value to be encoded
</td>
<td>PHP 5.5.0</td>
</tr>
<tr>
<td><strong><code><?=JSON_ERROR_UNSUPPORTED_TYPE; ?></code></strong></td>
<td><strong><code>JSON_ERROR_UNSUPPORTED_TYPE</code></strong></td>
<td>A value of a type that cannot be encoded was given</td>
<td>PHP 5.5.0</td>
</tr>
<tr>
<td><strong><code><?=JSON_ERROR_INVALID_PROPERTY_NAME; ?></code></strong></td>
<td><strong><code>JSON_ERROR_INVALID_PROPERTY_NAME</code></strong></td>
<td>A property name that cannot be encoded was given</td>
<td>PHP 7.0.0</td>
</tr>
<tr>
<td><strong><code><?=JSON_ERROR_UTF16; ?></code></strong></td>
<td><strong><code>JSON_ERROR_UTF16</code></strong></td>
<td>Malformed UTF-16 characters, possibly incorrectly encoded</td>
<td>PHP 7.0.0</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>[/code]

ส่งค่าตัวแปรในเช็กบ็อกซ์โดย jQuery

เขียนระบบ update ข้อมูลโดยใช้ ajax แต่ปัญหาคือ ใน form นี้มันมี input อยู่หลายตัว และเพราะว่าต้องการแค่ input ที่ชื่อ items[] ตัวเดียวเท่านั้น ถ้าส่ง data ไปโดยใช้ jQuery โดยปกติจะส่งค่าไปโดยใช้ .serialize() หรือ .serializeArray() ก็จะส่งตัวแปรอื่นๆ ที่ไม่จำเป็นติดไปด้วย จนทำให้ url ยาวจนเกิน limit ทำให้ต้องหาวิธีส่งไปเฉพาะตัวที่ใช้จริงๆ เท่านั้น

ตัวอย่างการส่งค่าไปในแบบ array[code language=”html” title=”checkbox_to_array.html”]
<!doctype html>
<html>

<head>
<meta charset="utf-8">
<title>checkbox to array</title>
</head>

<body>
<ul>
<li>
<input name="items[]" type="checkbox" value="c1">
</li>
<li>
<input name="items[]" type="checkbox" value="c2">
</li>
<li>
<input name="items[]" type="checkbox" value="c3">
</li>
<li>
<input name="items[]" type="checkbox" value="c4">
</li>
<li>
<input name="items[]" type="checkbox" value="c5">
</li>
<li>
<input name="items[]" type="checkbox" value="c6">
</li>
<li>
<input name="items[]" type="checkbox" value="c7">
</li>
<li>
<input name="items[]" type="checkbox" value="c8">
</li>
<li>
<input name="items[]" type="checkbox" value="c9">
</li>
<li>
<input name="items[]" type="checkbox" value="c10">
</li>
</ul>
<div id="result"></div>
<button id="sendBtn" type="submit">Send</button>
<script src="jquery-3.1.1.min.js"></script>
<script>
$(function() {

$(‘#sendBtn’).click(function() {
var checkboxs = $(‘input[name="items\\[\\]"]:checked’);

alert(‘checked ‘ + checkboxs.length + ‘ items’);

var values = checkboxs.map(function() {
return $(this).val();
})
.get();

var params = {
"id": 24,
"items": values,
};
$.ajax({
"data": params,
"success": function(data) {
$(‘#result’).html(data);
},
"type": "GET",
"url": "processing.php",
});

});

});
</script>
</body>

</html>[/code]

ตัวอย่างการส่งค่าไปในแบบ string[code language=”html” title=”checkbox_to_string.html”]
<!doctype html>
<html>

<head>
<meta charset="utf-8">
<title>checkbox to string</title>
</head>

<body>
<ul>
<li>
<input name="items[]" type="checkbox" value="c1">
</li>
<li>
<input name="items[]" type="checkbox" value="c2">
</li>
<li>
<input name="items[]" type="checkbox" value="c3">
</li>
<li>
<input name="items[]" type="checkbox" value="c4">
</li>
<li>
<input name="items[]" type="checkbox" value="c5">
</li>
<li>
<input name="items[]" type="checkbox" value="c6">
</li>
<li>
<input name="items[]" type="checkbox" value="c7">
</li>
<li>
<input name="items[]" type="checkbox" value="c8">
</li>
<li>
<input name="items[]" type="checkbox" value="c9">
</li>
<li>
<input name="items[]" type="checkbox" value="c10">
</li>
</ul>
<div id="result"></div>
<button id="sendBtn" type="submit">Send</button>
<script src="jquery-3.1.1.min.js"></script>
<script>
$(function() {

$(‘#sendBtn’).click(function() {
var checkboxs = $(‘input[name="items\\[\\]"]:checked’);

alert(‘checked ‘ + checkboxs.length + ‘ items’);

var values = checkboxs.map(function() {
return $(this).val();
})
.get()
.join();

alert(‘values = ‘ + values);

var encoded = encodeURIComponent(values);

alert(‘URL encoded = ‘ + encoded);

var decoded = decodeURIComponent(encoded);

alert(‘URL decoded = ‘ + decoded);

$.ajax({
"data": ‘id=24&items=’ + encoded,
"success": function(data) {
$(‘#result’).html(data);
},
"type": "GET",
"url": "processing.php",
});

});

});
</script>
</body>

</html>[/code]

ตัวอย่างการนำค่าไปเขียนเป็น sql query[code language=”php” title=”processing.php”]
<dl>
<dt>method="GET"</dt>
<dd><?=print_r($_GET, true);?></dd>
<dt>method="POST"</dt>
<dd><?=print_r($_POST, true);?></dd>
</dl>
<?php
if (is_array($_REQUEST[‘items’])) {
echo ‘<br>send items by array’;
$where = "WHERE id IN(‘" . implode("’, ‘", $_REQUEST[‘items’]) . "’)";
} else {
echo ‘<br>send items by string’;
$where = "WHERE id IN(‘" . str_replace(‘,’, "’, ‘", $_REQUEST[‘items’]) . "’)";
}

$query = "SELECT *
FROM table_name
$where;";

echo ‘<br>example query = ‘ . $query;[/code]

เลือกใช้การส่งแบบสตริงหรืออาร์เรย์ ก็แล้วแต่ความสดวก ที่ต้องนำไป loop อีกหรือแค่ใช้ในการสร้างเอสคิวแอลคิวรีอย่างเดียว

แบ่งชื่อ นามสกุล คำนำหน้านาม

โจทย์คือการ import ข้อมูลจาก excel เข้าไปเก็บใน database ซึ่งมันก็ไม่ซับซ้อนอะไรถ้าคำนำหน้านาม ชื่อ ชื่อกลาง นามสกุลมันไม่อยู่ในช่องเดียวกัน แต่ในตารางต้องการให้แยกไว้คนละฟิลย์เพื่อความสดวกในการดึงข้อมูล

ดูง่ายๆ แค่ตัดสตริงค์ตามช่องว่างก็น่าจะได้ แต่อย่างชื่อผม นาย พิชญ์ พันธุ์สนิท และชื่อ นาง ธิติมา แอน ประทุมทิพย์ ต่างกันคือ ตัดออกมาได้อาร์เรย์สมาชิก 3 ตัว และ 4 ตัว ก็เขียนเงื่อนไขได้ง่ายๆ ถ้ามี 4 ตัวก็แสดงว่ามี ชื่อกลาง

title = นาย
firstname = พิชญ์
middlename =
lastname = พันธุ์สนิท

และ
title = นาง
firstname = ธิติมา
middlename = แอน
lastname = ประทุมทิพย์

เขียน if (count($temp) == 4) ก็ได้แล้ว

แต่อย่าง ว่าที่ ร.ต.(หญิง) เต็มศิริ วีรสุข ถ้าใช้วิธี[code language=”php”]
list($title, $firstname, $middlename, lastname) = explode(‘ ‘, ‘ว่าที่ ร.ต.(หญิง) เต็มศิริ วีรสุข’);[/code]แล้วออกมาเป็น

title = ว่าที่
firstname = ร.ต.
middlename = (หญิง)
lastname = เต็มศิริ

คงไม่งาม และบางราชชื่อไม่มีคำนำหน้านาม (hr ผู้น่ารัก)

โชคดีที่มีคำนำหน้านามไม่เยอะเพราะฉะนั้นใช้วิธีใส่ในอาร์เรย์แล้วเอาไป search หาเอาก็ได้[code language=”php”]
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>แบ่งชื่อ นามสกุล คำนำหน้านาม</title>
</head>
<body>
<?php

$names = [
‘ซาร่า มาลา กุล เลน ณ อยุธยา’,
‘นพ.เหรียญทอง แน่นหนา’,
‘นักเทคนิคการแพทย์ภาคภูมิ เดชหัสดิน’,
‘นางธิติมา แอน ประทุมทิพย์’,
‘นายพิชญ์ พันธุ์สนิท’,
‘ว่าที่ ร.ต.(หญิง) เต็มศิริ วีรสุข’,
];

$titles = [
‘นพ.’,
‘นักเทคนิคการแพทย์’,
‘นาง’,
‘นาย’,
‘ว่าที่ ร.ต.(หญิง)’,
];

$results = [];
foreach ($names as $no => $name) {

$temp = str_replace($titles, ‘<> ‘, $name);
$temp = mb_ereg_replace(‘/\s+/’, ‘\s’, $temp);
$temp = array_values(array_filter(explode(‘ ‘, $temp)));

if ($temp[0] == ‘<>’) {
$results[$no][‘title’] = substr($name, 0, strpos($name, $temp[1]));
} else {
$results[$no][‘title’] = ”;
array_unshift($temp, ”);
}

$results[$no][‘firstname’] = $temp[1];
if (count($temp) == 4) {
$results[$no][‘middlename’] = $temp[2];
$results[$no][‘lastname’] = $temp[3];
} else {
unset($temp[0], $temp[1]);
$results[$no][‘middlename’] = ”;
$results[$no][‘lastname’] = implode(‘ ‘, $temp);
}
}

echo ‘<pre>’, print_r($results, true), ‘</pre>’;
?>
</body>
</html>
[/code]ผลลัพธ์ คือ[code language=”text”]
Array
(
[0] => Array
(
[title] =>
[firstname] => ซาร่า
[middlename] =>
[lastname] => มาลา กุล เลน ณ อยุธยา
)

[1] => Array
(
[title] => นพ.
[firstname] => เหรียญทอง
[middlename] =>
[lastname] => แน่นหนา
)

[2] => Array
(
[title] => นักเทคนิคการแพทย์
[firstname] => ภาคภูมิ
[middlename] =>
[lastname] => เดชหัสดิน
)

[3] => Array
(
[title] => นาง
[firstname] => ธิติมา
[middlename] => แอน
[lastname] => ประทุมทิพย์
)

[4] => Array
(
[title] => นาย
[firstname] => พิชญ์
[middlename] =>
[lastname] => พันธุ์สนิท
)

[5] => Array
(
[title] => ว่าที่ ร.ต.(หญิง)
[firstname] => เต็มศิริ
[middlename] =>
[lastname] => วีรสุข
)

)
[/code]อธิบาย[code language=”php”]
$temp = str_replace($titles, ‘<> ‘, $name);[/code]เปลี่ยนคำนำหน้านามเป็นตัวอื่นก่อน[code language=”php”]
$temp = mb_ereg_replace(‘/\s+/’, ‘\s’, $temp);[/code]เอาสเปซที่มีมากกว่า 1 ตำแหน่งแทนที่ด้วยช่องว่าแค่ 1 ตำแหน่งก็พอ[code language=”php”]
$temp = array_values(array_filter(explode(‘ ‘, $temp)));[/code]แบ่งข้อมูลออกเป็นส่วนๆ โดย array_values(array_filter()) จะทำให้อินเด็กซ์ของอาร์เรย์เป็นไปตามลำดับ[code language=”php”]
array_unshift($temp, ”);[/code]ถ้าไม่มีคำนำหน้านามก็ใส่ให้มัน ลำดับอาร์เรย์จะได้ไม่เคลื่อนไป[code language=”php”]$results[$no][‘lastname’] = implode(‘ ‘, $temp);[/code]เพราะว่าบางคน นามสกุล จะมีช่องว่างจำนวนมาก เช่น มาลา กุล เลน ณ อยุธยา และถ้าแบ่งข้อมูลผิด ผลลัพธ์ที่ได้ก็ไม่น่าเกลียดเท่าไหร่