Tag Archive query string

curl: ส่งไฟล์

และแล้วก็มาถึงจุดที่รอคอย การส่งไฟล์ด้วย curl เหมือนที่ user upload ไฟล์เข้าเว็บ เหมาะกับการเอาไปเขียนโปรแกรมทรานสเฟอร์ไฟล์จากเว็บหนึ่งไปอีกที่หนึ่ง หรือจะเขียน bot ส่งไฟล์ออกไปเก็บเป็นข้อมูลสำรองก็ได้

<!doctype html>
<html>

<head>
    <meta charset="utf-8">
    <title>CURL: send file</title>
    <link href="../vendor/twbs/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet" type="text/css">
</head>

<body>
    <div class="container">
        <?php
if (count($_FILES) || count($_POST)) {
    $url = 'http://localhost/snippets/PHP/variables.php';

    if (count($_FILES)) {
        $file_name_with_full_path = $_FILES['avatar']['tmp_name'];

        if (function_exists('curl_file_create')) {
            /* php 5.5+ */
            $_POST['avatar'] = curl_file_create($file_name_with_full_path);
        } else {
            $_POST['avatar'] = '@' . realpath($file_name_with_full_path);
        }
    }

    $ch = curl_init();

    curl_setopt_array($ch, [
        CURLOPT_ENCODING => 'UTF-8',
        CURLOPT_POST => 1,
        CURLOPT_POSTFIELDS => $_POST,
        //CURLOPT_POSTFIELDS => http_build_query($_POST),
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_URL => $url,
    ]);

    $result = curl_exec($ch);
    curl_close($ch);

    echo $result;
}
?>
            <form action="curl_file.php" enctype="multipart/form-data" method="post">
                <div class="form-group">
                    <label for="name">Name:</label>
                    <input class="form-control" id="name" name="name" type="text">
                </div>
                <div class="form-group">
                    <label for="avatar">Avatar:</label>
                    <input accept="image/gif, image/jpeg, image/x-png" class="form-control" id="avatar" name="avatar" type="file">
                </div>
                <div class="form-group">
                    <label for="address1">text address:</label>
                    <input class="form-control" id="address1" name="address[d]" type="text">
                </div>
                <div class="form-group">
                    <label for="address2">text address 2:</label>
                    <input class="form-control" id="address2" name="address[f]" type="text">
                </div>
                <button type="submit" class="btn btn-default">Submit</button>
            </form>
    </div>
</body>

</html>

แต่เพราะ bug ของ function http_build_query ไม่สามารถ encoded query string ในกรณีที่มีไฟล์ได้อย่างถูกต้อง ทำให้ต้องส่งค่าฟอร์มไปโดยไม่เข้ารหัส ดังนั้น ค่าที่เป็น array จึงส่งค่าออกไปผิด

[address]Array
(
    [name] => pitt phunsanit
    [address] => Array
)

จากที่ค้นหาข้อมูลดู ยังไม่มีวิธีที่แก้ปัญหานี้ได้โดยไม่มีผลอาการข้างเคียง คงต้องรอให้ทางทีมงานพัฒนา PHP แก้ปัญหาให้ ตอนนี้ก็พยามหลีกเลี่ยงการส่งข้อมูลแบบเป็นอาร์เรไปก่อน อาจจะใช้ implode รวมข้อมูลก่อนส่งไปก็ได้

curl: ส่ง ฟอร์มแบบ post

หลังจากตัวอย่าง curl: ส่ง ฟอร์มแบบ get เรามาลองส่งข้อมูลแบบโพสต์กันต่อ เว็บไซต์ส่วนใหญ่จะนิยมส่งค่าในแบบฟอร์มแบบ post มากกว่าแบบ get เพราะว่า url จะดูสวยงาม ไม่เละเทะ ดูแล้วสบายตา และปลอดภัยกว่าการส่ข้อมูลให้เห็นง่ายๆ แบบใช้ url

<!doctype html>
<html>

<head>
    <meta charset="utf-8">
    <title>CURL: send post variables</title>
    <link href="../vendor/twbs/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet" type="text/css">
</head>

<body>
    <div class="container">
        <?php
if (count($_POST)) {
    $url = 'http://localhost/snippets/PHP/variables.php';

    $ch = curl_init();

    curl_setopt_array($ch, [
        CURLOPT_ENCODING => 'UTF-8',
        CURLOPT_POST => 1,
        CURLOPT_POSTFIELDS => http_build_query($_POST),
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_URL => $url,
    ]);

    $result = curl_exec($ch);
    curl_close($ch);

    echo $result;
}
?>
            <form action="curl_post.php" enctype="multipart/form-data" method="post">
                <div class="form-group">
                    <label for="name">Name:</label>
                    <input class="form-control" id="name" name="name" type="text">
                </div>
                <div class="form-group">
                    <label for="avatar">Avatar:</label>
                    <input accept="image/gif, image/jpeg, image/x-png" class="form-control" id="avatar" name="avatar" type="file">
                </div>
                <div class="form-group">
                    <label for="address1">text address:</label>
                    <input class="form-control" id="address1" name="address[]" type="text">
                </div>
                <div class="form-group">
                    <label for="address2">text address 2:</label>
                    <input class="form-control" id="address2" name="address[]" type="text">
                </div>
                <button type="submit" class="btn btn-default">Submit</button>
            </form>
    </div>
</body>

</html>

จากการเปลี่ยน option ของ curl เล็กน้อยการส่งข้อมูลก็เปลี่ยนไปเป็นแบบ method post แล้ว แต่ก็ยังส่งไฟล์ไปไม่ได้อยู่ดีๆ ใจเย็นๆ ครับบทความหน้าส่งไฟล์ออกไปแน่ๆ ครับ

curl: ส่ง ฟอร์มแบบ get

curl หรือ Client URL Library เป็น function ที่ทำให้ php ทำตัวเป็น browser ที่ใช้เปิดเว็บรับส่งข้อมูลต่างๆ จาก server ของเราไปเซิฟเวอร์เครื่องอื่นๆ

ตัวอย่างการใช้งานที่ง่ายที่สุด คือการใช้ curl โดยการจำลองการส่งข้อมูลจากฟอร์มแบบเมธอดเก็ต หรือที่เรียกง่ายๆว่า ส่งข้อมูลแบบ url นั่นละ

<!doctype html>
<html>

<head>
    <meta charset="utf-8">
    <title>CURL: send get variables</title>
    <link href="../vendor/twbs/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet" type="text/css">
</head>

<body>
    <div class="container">
        <?php
if (count($_GET)) {
    $queryString = http_build_query($_GET);
    $url = 'http://localhost/snippets/PHP/variables.php?' . $queryString;

    echo '<br>$url = ', $url;

    $ch = curl_init();

    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_URL => $url,
    ]);

    $result = curl_exec($ch);
    curl_close($ch);

    echo $result;
}
?>
            <form action="curl_get.php" method="get">
                <div class="form-group">
                    <label for="name">Name:</label>
                    <input class="form-control" id="name" name="name" type="text">
                </div>
                <div class="form-group">
                    <label for="avatar">Avatar:</label>
                    <input accept="image/gif, image/jpeg, image/x-png" class="form-control" id="avatar" name="avatar" type="file">
                </div>
                <div class="form-group">
                    <label for="address1">text address:</label>
                    <input class="form-control" id="address1" name="address[]" type="text">
                </div>
                <div class="form-group">
                    <label for="address2">text address 2:</label>
                    <input class="form-control" id="address2" name="address[]" type="text">
                </div>
                <button type="submit" class="btn btn-default">Submit</button>
            </form>
    </div>
</body>

</html>

ในการแปลงข้อมูลจากแบบฟอร์มจะใช้

$queryString = http_build_query($_GET);

แปลงให้อยู่ในรูปแบบคิวรี่สตริงที่ส่งไปกับ url ได้

การทดสอบทำได้โดยไฟล์ variables.php จำลองเป็นฝั่งรับข้อมูล

<?php
echo '<h3>$_COOKIE</h3><pre>', print_r($_COOKIE, true), '</pre>';
echo '<h3>$_FILES</h3><pre>', print_r($_FILES, true), '</pre>';
echo '<h3>$_GET</h3><pre>', print_r($_GET, true), '</pre>';
echo '<h3>$_POST</h3><pre>', print_r($_POST, true), '</pre>';
echo '<h3>$_REQUEST</h3><pre>', print_r($_REQUEST, true), '</pre>';

ข้อมูลที่ส่งไปจะแสดงกลับมาให้เราเห็น แต่สังเกตุได้ว่า ถึงจะส่งไฟล์ avatar ฝั่งรับก็จะไม่ได้รับ เพราะการส่งข้อมูลแบบนี้จะมีข้อเสียคือ ไม่สามารถส่งไฟล์ได้

ตัวแปร get ใน javascript

ในภาษา Javascript ไม่มี function ที่ทำหน้าที่รับตัวแปรจาก URL ดังนันจึงต้องใช้วิธีตัด string ทั้งหมด 3 ครั้ง

  1. แยกส่วนตัวแปรออกมา (หลังเครื่องหมาย ?)
  2. แยกตัวแปรออกเป็นชุดๆ (คั่นโดย &)
  3. แยกตัวแปรและค่าออกจากกัน (คั่นโดย =)
function getURIParams(uri)
{
    var params = [], hash;
    var hashes = uri.slice(uri.indexOf('?') + 1).split('&');
    for(var a = 0; a < hashes.length; a++)
    {
        hash = hashes[a].split('=');
        params[hash[0]] = hash[1];
    }
    return params;
}

ตัวอย่างวิธีใช้

uri = document.location
params = getURIParams(uri);
msg = '';
for(index in params)
{
	msg = msg+'n'+index+'='+params[index];
}
alert(msg);

ตอน test อย่าลืมใส่ตัวแปรใน url ต่อท้ายด้วย เช่น
test.html?one=1&two=2
ก่อน refresh