您如何从AJAX调用的PHP文件中回显SQL SELECT语句?

时间:2018-08-09 15:37:57

标签: php mysql ajax

每个文件中都有很多代码,要发布的代码太多了,因此,我为您提供了每个文件中发生情况的大致信息。

index.php     [html下拉菜单代码等]

scripts.js     [AJAX从下拉列表中检测到用户选择,抓取了fetch.php,后者将数据库拉出以生成用于辅助下拉列表选择的html代码,并将其放入index.php中]

fetch.php     [根据用户选择和数据库查询生成辅助下拉代码]

我需要查看确切要调试的内容,所以我想回显sql select语句:

$query = "SELECT * FROM databasename WHERE.."

当用户从fetch.php中进行选择时,它位于index.php中-我该怎么做?

2 个答案:

答案 0 :(得分:5)

当我处理AJAX时,我以JSON返回,我使用的一个技巧是利用输出缓冲。您不能只回显或输出所需的任何内容,因为它会弄乱JSON数据,因此举个例子,

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.

这是将脚本的所有输出包装到JSON数据中,以免格式混乱。

然后在javascript端,您可以使用console.log

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

如果您不习惯使用console.log()进行调试,通常可以点击F12并在大多数浏览器中打开调试器。然后在那里,输出将被发送到“控制台”。我记得IE9与console.log()有点问题,但我不想走得太远。

注意:,只需确保在将其移至生产环境时不要在代码中保留这些内容,只需将这一行注释掉就非常简单,

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

然后您的调试信息将不会在生产中公开。还有其他自动执行此操作的方法,但这取决于您是否进行本地开发然后发布到服务器。例如,您可以在$_SERVER['SERVER_ADDR'];或本地::1上的127.0.0.1上切换它。这有一些缺点,主要是无法从命令行界面(CLI)获得服务器地址。因此,通常我会将其绑定到一个全局常量中,该常量说明网站处于哪种“模式”(包括在公共入口点中,通常是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);

然后检查它很简单:

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

如果您知道如何使用错误报告,甚至可以使用

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

仅在显示错误打开时才会显示调试。

希望有帮助。

更新

因为我在评论中提到了它,所以下面是将它包装在一个类中的示例(这是简化版本,因此我没有对其进行测试)

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

}

然后,当您做出AJAX响应时,只需像这样包装它(注意$ result是通过引用传递的,这样我们就不必做返回,并且在例外情况下,我们将$ result更新为“ real时间”,而不是完成时间

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

如果您需要将其他数据传递到闭包中,请不要忘记可以像这样使用use语句。

$otherdata = 'bar';

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

Sandbox

如果环境正确(已注释掉),则此方法可捕获所有输出并将其置于调试状态。请请确保实施某种保护,以使输出内容不会在生产时发送给客户,我不能强调太多。它还捕获任何将其放入错误的异常。并且还处理标头和编码。

此功能的一大好处是JSON的结构一致,您将知道(在客户端)如果if(data.userdata.error),则在后端有一个异常。它为您提供了一个调整标头,JSON编码等的地方...

PHP7中的一个注释,您必须或应该添加Throwable接口(而不是Exception)。如果要捕获Error和Exception类,或者执行两个catch块。

让我们说我做了很多AJAX并一直讨厌重写它,我的实际课程比这还要广泛,但这就是要点。

干杯。

UPDATE1

  

要显示的内容,我要做的一件事是在console.log()之前解析数据变量

这通常是因为您没有将正确的标头传递回浏览器。如果发送(在调用json_encode之前)

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

这只是让浏览器知道它返回的数据类型。大多数人忘记的一件事是,在网络上所有回复都是以文本形式完成的。甚至图像或文件下载以及网页。都是文本,使文本变得特别的是浏览器认为的Content-Type

关于header的一件事要注意,您不能在发送标题之前输出任何内容。但是,这与我发布的代码配合得很好,因为该代码将捕获所有输出,并在发送标头后将其发送。

我将原始代码更新为具有标头,我将其保存在稍后发布的更复杂的类中。但是,如果在其中添加它,则无需手动解析JSON。

我要提到的最后一件事是检查是否返回了JSON或文本,如果在开始输出缓冲之前发生一些错误,您仍然可以获取文本。

有两种方法可以做到这一点。

如果Data是需要解析的字符串

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

或者,如果您具有标题及其始终为JSON的标题,那么它会更简单

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

希望有帮助!

UPDATE2

因为这个话题很多,所以我在GitHub上放置了上述代码的修改版本,您可以在这里找到它。

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

答案 1 :(得分:0)

回显内容并执行die()或退出;然后...,然后在浏览器的“网络”选项卡中,开始记录,运行Ajax请求(它将失败),但检查资源/名称,然后查看“响应”,它将向您显示回显了什么在脚本中

来自:Request Monitoring in Chrome

Chrome当前内置了一个解决方案。

使用CTRL + SHIFT + I(或导航到“当前页面控件”>“开发人员”>“开发人员工具”。

在较新版本的Chrome中,点击扳手图标>工具>开发人员工具。)以启用开发人员工具。

在开发人员工具中,单击“网络”按钮。如果尚未启用,请在会话中启用它,或者始终启用它。

点击“ XHR”子按钮。

发起AJAX调用。

您将在“资源”下方的左栏中看到项目。

单击资源,有两个选项卡显示标题和返回内容。


其他浏览器也具有“网络”选项卡,但是您需要使用我的注释来获取查询的字符串值。

上面的ArtisticPhoenix解决方案很令人愉快。