sql >> Databáze >  >> RDS >> Mysql

Jak zopakujete příkaz SQL SELECT ze souboru PHP nazývaného AJAX?

Když se zabývám AJAXem, který se vracím jako JSON, jeden trik, který používám, je využít výstupní vyrovnávací paměti. Nemůžete jen echo nebo výstup cokoli chcete, protože to zkazí data JSON, takže například

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.

Co to dělá, je zabalit jakýkoli výstup z vašeho skriptu do vašich dat JSON, aby nebyl narušen jeho formát.

Pak na straně javascriptu můžete použít console.log

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

Pokud nejste zvyklí na ladění pomocí console.log() , obvykle můžete stisknout F12 a otevřete ladicí program ve většině prohlížečů. Poté bude výstup odeslán do "konzole". IE9 měl trochu problém s console.log() pokud si vzpomínám, ale nechci jít daleko od cesty.

POZNÁMKA: Jen se ujistěte, že tyto věci v kódu nenecháte, když jej přesunete do produkce, je velmi jednoduché tento řádek okomentovat,

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

A pak vaše ladicí informace nebudou vystaveny ve výrobě. Existují i ​​jiné způsoby, jak to automaticky provést, ale záleží na tom, zda provádíte místní vývoj a poté publikujete na server. Můžete jej například přepnout na $_SERVER['SERVER_ADDR']; což bude ::1 nebo 127.0.0.1 když je to místní. To má několik nevýhod, zejména adresa serveru není dostupná z rozhraní příkazového řádku (CLI). Obvykle to tedy spojím do globální konstanty, která říká, v jakém "režimu" se web nachází (zahrnuto ve společném vstupním bodu, obvykle 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);

Pak je jednoduché to zkontrolovat:

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

Pokud víte, jak používat hlášení chyb, můžete se s tím dokonce spojit pomocí

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

Což zobrazí ladění pouze při zapnutém zobrazení chyb.

Doufám, že to pomůže.

AKTUALIZACE

Protože jsem to zmínil v komentářích, zde je jeho příklad zabalený do třídy (toto je zjednodušená verze, takže jsem to netestoval)

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;
   }

}

Když pak uděláte odpověď AJAX, jednoduše ji zabalíte takto (pozn. $result je předán odkazem, tímto způsobem se nemusíme vracet a v případě výjimky místo toho aktualizujeme $result v "reálném čase" z po dokončení)

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

Pokud potřebujete do uzávěrky předat další data, nezapomeňte, že můžete použít use prohlášení, jako je toto.

$otherdata = 'bar';

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

Sandbox

To se postará o zachycení jakéhokoli výstupu a vloží jej do ladění, pokud je prostředí správné (zakomentováno). Prosím, ujistěte se, že implementujete nějaký druh ochrany, aby výstup nebyl zasílán klientům do výroby, nemohu to dostatečně zdůraznit. Zachytí také všechny výjimky a způsobí chybu. A také zpracovává záhlaví a kódování.

Jednou z velkých výhod je konzistentní struktura vašeho JSON, budete vědět (na straně klienta), že pokud if(data.userdata.error) pak máte na zadní straně výjimku. Poskytuje vám jedno místo pro vyladění záhlaví, kódování JSON atd...

Jedna poznámka v PHP7 budete muset nebo byste měli přidat rozhraní Throwable (místo výjimky). Pokud chcete zachytit třídy Error a Exception Nebo proveďte dva catch bloky.

Řekněme, že dělám hodně AJAX a už mě nebavilo to pořád přepisovat, moje skutečná třída je rozsáhlejší než tohle, ale to je podstata toho.

Na zdraví.

AKTUALIZACE 1

To je obvykle proto, že nepředáváte správné záhlaví zpět do prohlížeče. Pokud odešlete (těsně před voláním json_encode)

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

To jen dává prohlížeči vědět, jaký typ dat získává zpět. Jedna věc, kterou většina lidí zapomíná, je, že na webu jsou všechny odpovědi prováděny v textu. Dokonce i obrázky nebo stahování souborů a webové stránky. Všechno je to jen text, co z něj dělá něco zvláštního je Content-Type že si to prohlížeč myslí.

Jedna věc k poznámce o header je, že před odesláním záhlaví nemůžete nic vypsat. To se však dobře hraje s kódem, který jsem zveřejnil, protože tento kód zachytí veškerý výstup a odešle jej po odeslání hlavičky.

Aktualizoval jsem původní kód, aby měl záhlaví, měl jsem ho ve složitější třídě, kterou jsem zveřejnil později. Ale pokud přidáte, že v něm byste se měli zbavit nutnosti ručně analyzovat JSON.

Poslední věc, kterou bych měl zmínit, je zkontrolovat, zda se mi vrátil JSON nebo text, stále můžete dostat text v případě, že dojde k nějaké chybě před zahájením ukládání do vyrovnávací paměti.

Existují 2 způsoby, jak to udělat.

Pokud je Data řetězec, který je třeba analyzovat

$.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.
          }
    }
    //....
}

Nebo pokud máte hlavičku a její vždy JSON, pak je to o něco jednodušší

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

Doufám, že to pomůže!

AKTUALIZACE 2

Protože se toto téma často objevuje, umístil jsem upravenou verzi výše uvedeného kódu na svůj GitHub, najdete ji zde.

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



  1. Vložení SQL dotazu do funkce PHP

  2. Chyba syntaxe jednoduchého dotazu na tabulku?

  3. Při ukládání záznamu se nevkládá konkrétní sloupec

  4. mysql vygeneruje chybějící data s předchozí hodnotou