Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Bagaimana Anda menggemakan pernyataan SQL SELECT dari file PHP yang dipanggil oleh AJAX?

Ketika saya berurusan dengan AJAX, yang saya kembalikan sebagai JSON, salah satu trik yang saya gunakan adalah memanfaatkan buffering output. Anda tidak bisa hanya menggemakan atau menampilkan apa pun yang Anda inginkan karena itu akan mengacaukan data JSON jadi misalnya,

ob_start(); //turn on buffering at beginning of script.

.... other code ...

print_r($somevar);

.... other code ...

$debug = ob_get_clean();  //put output in a var
$data['debug'] = $debug;

header('Content-Type: application/json');
echo json_encode($data); //echo JSON data.

Fungsinya adalah membungkus semua keluaran dari skrip Anda ke dalam data JSON Anda sehingga formatnya tidak kacau.

Kemudian di sisi javascript Anda dapat menggunakan console.log

$.post(url, input, function(data){
   if(data.debug) console.log(data.debug);
});

Jika Anda tidak terbiasa men-debug dengan console.log() , Anda biasanya dapat menekan F12 dan buka debugger di sebagian besar browser. Kemudian di sana output akan dikirim ke "konsol". IE9 memiliki sedikit masalah dengan console.log() jika saya ingat, tetapi saya tidak ingin pergi jauh.

CATATAN: Pastikan untuk tidak meninggalkan hal ini dalam kode saat Anda memindahkannya ke produksi, sangat mudah untuk hanya mengomentari baris ini,

//$data['debug'] = $debug;

Dan kemudian informasi debug Anda tidak akan diekspos dalam produksi. Ada cara lain untuk melakukan ini secara otomatis, tetapi itu tergantung pada apakah Anda melakukan pengembangan lokal kemudian mempublikasikan ke server. Misalnya Anda dapat mengaktifkannya di $_SERVER['SERVER_ADDR']; yang akan menjadi ::1 atau 127.0.0.1 ketika itu lokal. Ini memiliki beberapa kelemahan, terutama alamat server tidak tersedia dari Command Line Interface (CLI). Jadi biasanya saya akan mengikatnya ke dalam konstanta global yang menyatakan "mode" situs tersebut (termasuk dalam titik masuk umum, biasanya index.php).

if(!defined('ENV_DEVELOPMENT')) define('ENV_DEVELOPMENT','DEVELOPMENT');

if(!defined('ENV_PRODUCTION')) define('ENV_PRODUCTION','PRODUCTION');

if(!defined('ENVIRONMENT')) define('ENVIRONMENT',ENV_DEVELOPMENT);
//site is in Development mode, uncomment for production
//if(!defined('ENVIRONMENT')) define('ENVIRONMENT',ENV_DEVELOPMENT);

Maka itu adalah masalah sederhana untuk memeriksanya:

if(ENVIRONMENT == ENV_PRODUCTION ) $data['debug'] = $debug;

Jika Anda tahu cara menggunakan pelaporan kesalahan, Anda bahkan dapat mengaitkannya dengan menggunakan

 if(ini_get('display_errors') == 1) $data['debug'] = $debug;

Yang hanya akan menampilkan debug saat kesalahan tampilan aktif.

Semoga membantu.

PERBARUI

Karena saya menyebutkannya di komentar, berikut adalah contoh yang dibungkus dalam kelas (ini adalah versi yang disederhanakan, jadi saya tidak mengujinya)

class LibAjax{
    public static function respond($callback, $options=0, $depth=32){
        $result = ['userdata' => [
              'debug' => false,
              'error' => false
        ]];

        ob_start();

         try{

             if(!is_callable($callback)){
                //I have better exception in mine, this is just more portable
                throw new Exception('Callback is not callable');
             }

             $callback($result);
         }catch(\Exception $e){
              //example 'Exception[code:401]'
             $result['userdata']['error'] = get_class($e).'[code:'.$e->getCode().']';
            //if(ENVIRONMENT == ENV_DEVELOPMENT){
            //prevents leaking data in production
                $result['userdata']['error'] .= ' '.$e->getMessage();
                $result['userdata']['error'] .= PHP_EOL.$e->getTraceAsString();
            //}
         }

         $debug = '';
         for($i=0; $i < ob_get_level(); $i++){
             //clear any nested output buffers
             $debug .= ob_get_clean();
         }
         //if(ENVIRONMENT == ENV_DEVELPMENT){
             //prevents leaking data in production
              $result['userdata']['debug'] = $debug;
        //}
         header('Content-Type: application/json');
         echo self::jsonEncode($result, $options, $depth);
   }

   public static function jsonEncode($result, $options=0, $depth=32){
       $json = json_encode($result, $options, $depth);
       if(JSON_ERROR_NONE !== json_last_error()){
           //debug is not passed in this case, because you cannot be sure that, that was not what caused the error.  Such as non-valid UTF-8 in the debug string, depth limit, etc...
           $json = json_encode(['userdata' => [
              'debug' => false,
              'error' => json_last_error_msg()
           ]],$options);
       }
       return $json;
   }

}

Kemudian ketika Anda membuat respons AJAX, Anda cukup membungkusnya seperti ini (perhatikan $result dilewatkan dengan referensi, dengan cara ini kami tidak harus melakukan pengembalian, dan dalam kasus pengecualian kami memperbarui $result dalam "waktu nyata" sebagai gantinya setelah selesai)

LibAjax::respond( function(&$result){
     $result['data'] = 'foo';
});

Jika Anda perlu memasukkan data tambahan ke dalam penutupan, jangan lupa Anda dapat menggunakan use pernyataan, seperti ini.

$otherdata = 'bar';

LibAjax::respond( function(&$result) use($otherdata){
     $result['data'][] = 'foo';
     $result['data'][] = $otherdata;
});

Kotak Pasir

Ini menangani penangkapan output apa pun dan memasukkannya ke dalam debug, jika lingkungannya benar (dikomentari). Mohon pastikan untuk menerapkan semacam perlindungan sehingga output tidak dikirim ke klien pada produksi, saya tidak bisa cukup menekankan itu. Itu juga menangkap pengecualian apa pun yang membuatnya salah. Dan juga menangani header dan encoding.

Satu manfaat besar untuk ini adalah struktur yang konsisten untuk JSON Anda, Anda akan tahu (di sisi klien) bahwa jika if(data.userdata.error) maka Anda memiliki pengecualian di bagian belakang. Ini memberi Anda satu tempat untuk mengubah header, enkode JSON, dll...

Satu catatan di PHP7 Anda harus atau harus menambahkan antarmuka Throwable (bukan Pengecualian). Jika Anda ingin menangkap kelas Kesalahan dan Pengecualian Atau lakukan dua blok tangkapan.

Anggap saja saya melakukan banyak AJAX dan bosan menulis ulang ini sepanjang waktu, kelas saya yang sebenarnya lebih luas dari ini, tapi itulah intinya.

Salam.

PERBARUI1

Ini biasanya karena Anda tidak meneruskan tajuk yang benar kembali ke browser. Jika Anda mengirim (tepat sebelum memanggil json_encode)

header('Content-Type: application/json');

Ini hanya memungkinkan browser mengetahui jenis data apa yang diperoleh kembali. Satu hal yang kebanyakan orang lupa adalah bahwa di web semua tanggapan dilakukan dalam teks. Bahkan gambar atau file download dan halaman web. Itu semua hanya teks, yang membuat teks itu menjadi sesuatu yang istimewa adalah Content-Type yang menurut browser seperti itu.

Satu hal yang perlu diperhatikan tentang header adalah Anda tidak dapat menampilkan apa pun sebelum mengirim tajuk. Namun ini cocok dengan kode yang saya posting karena kode itu akan menangkap semua output dan mengirimkannya setelah header dikirim.

Saya memperbarui kode asli untuk memiliki tajuk, saya memilikinya di kelas yang lebih kompleks yang saya posting nanti. Tetapi jika Anda menambahkannya di dalamnya, Anda tidak perlu lagi mem-parsing JSON secara manual.

Satu hal terakhir yang harus saya sebutkan saya lakukan adalah memeriksa apakah saya mendapatkan kembali JSON atau teks, Anda masih bisa mendapatkan teks jika terjadi beberapa kesalahan sebelum buffering output dimulai.

Ada 2 cara untuk melakukannya.

Jika Data adalah string yang perlu diuraikan

$.post(url, {}, function(data){
    if( typeof data == 'string'){
        try{
            data = $.parseJSON(data);
        }catch(err){
            data = {userdata : {error : data}};
        }
    }
    if(data.userdata){
          if( data.userdata.error){
               //...etc.
          }
    }
    //....
}

Atau jika Anda memiliki header dan selalu JSON, maka ini sedikit lebih sederhana

$.post(url, {}, function(data){
    if( typeof data == 'string'){
        data = {userdata : {error : data}};
    }
    if(data.userdata){
          if( data.userdata.error){
               //...etc.
          }
    }
    //....
}

Semoga membantu!

PERBARUI2

Karena topik ini sering muncul, saya menempatkan versi modifikasi dari kode di atas di GitHub saya, Anda dapat menemukannya di sini.

https://github.com/ArtisticPhoenix/MISC/blob/master /AjaxWrapper/AjaxWrapper.php



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bagaimana cara membuat MySQL memperlakukan garis bawah sebagai pemisah kata untuk pencarian teks lengkap?

  2. MySQL kurangi dari subquery yang terisolasi

  3. NHibernate akan memasukkan tetapi tidak memperbarui setelah pindah ke Host dengan server bersama yang menjalankan mysql

  4. Bagaimana cara mengembalikan id pada Sisipan dengan mybatis di mysql dengan anotasi

  5. Query MySql, Pilih lebih besar dari