您如何从AJAX调用的PHP文件中回显SQL SELECT语句? [英] How do you echo a SQL SELECT statement from a PHP file called by AJAX?

查看:57
本文介绍了您如何从AJAX调用的PHP文件中回显SQL SELECT语句?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

There's a lot of code in each file, too much to post, so I'm giving you a general idea of what's happening in each file.

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

index.php [html dropdown menu code etc.]

scripts.js[AJAX从下拉列表中检测到用户选择,抓取fetch.php并提取数据库以生成html代码,以便将第二个下拉列表选择内容放入index.php中.]

scripts.js [AJAX detects user selection from dropdown, grabs fetch.php which pulls database to generate html code for secondary dropdown selections to put in index.php]

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

fetch.php [Generates secondary dropdown code based on user selection and query of the database]

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

I need to see what exactly is being queried to debug, so I'd like to echo the sql select statement:

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

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

That is in fetch.php when user makes a selection from index.php - How do I do this?

推荐答案

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

When I deal with AJAX, that I return as JSON, one trick I use is to take advantage of output buffering. You can't just echo or output anything you want because it will mess up the JSON data so for an example,

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数据中,以免格式混乱.

What this does, is wrap any output from you script into your JSON data so that it's format is not messed up.

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

Then on the javascript side you can use console.log

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

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

If you are not used to debugging with console.log(), you can usually hit F12 and open the debugger in most browsers. Then in there the output will be sent to the "console". IE9 had a bit of an issue with console.log() if I recall, but I don't want to go to far off track.

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

NOTE: Just make sure to not leave this stuff in the code when you move it to production, its very simple to just comment this line out,

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

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

And then your debug information wont be exposed in production. There are other ways to automatically do this, but it depends on if you do development local then publish to the server. For example you can switch it on the $_SERVER['SERVER_ADDR']; which will be ::1 or 127.0.0.1 when it's local. This has a few drawbacks, mainly the server address is not available from the Command Line Interface (CLI). So typically I will tie it into a global constant that says what "mode" the site is in (included in the common entry point, typically 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 you know how to use error reporting you can even tie into that using

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

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

Which will only show the debug when display errors is on.

希望有帮助.

更新

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

Because I mentioned it in the comments, here is an example of it wrapped in a class (this is a simplified version, so I didn't test this)

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时间",而不是完成时间

Then when you make a AJAX response you just wrap it like this (note $result is pass by reference, this way we don't have to do return, and in the case of an exception we update $result in "real time" instead of on completion)

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

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

If you need to pass additional data into the closure don't forget you can use the use statement, like this.

$otherdata = 'bar';

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

沙盒

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

This handles catching any output and puts it in debug, if the environment is correct (commented out). Please pleas make sure to implement some kind of protection so that the output is not sent to clients on production, I cant stress that enough. It also catches any exceptions puts it in error. And it also handles the header and encoding.

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

One big benefit to this is consistent structure to your JSON, you will know (on the client side) that if if(data.userdata.error) then you have an exception on the back end. It gives you one place to tweak your headers, JSON encoding etc...

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

One note in PHP7 you'll have to or should add the Throwable interface (instead of Exception). If you want to catch Error and Exception classes Or do two catch blocks.

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

Let's just say I do a lot of AJAX and got sick of re-writing this all the time, my actual class is more extensive then this, but that's the gist of it.

干杯.

UPDATE1

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

One thing I had to do for things to display was to parse the data variable before I console.log() it

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

This is typically because you are not passing the correct header back to the browser. If you send (just before calling json_encode)

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

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

This just lets the browser know what type of data it is getting back. One thing most people forget is that on the web all responses are done in text. Even images or file download and web pages. It's all just text, what makes that text into something special is the Content-Type that the browser thinks it is.

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

One thing to note about header is you cannot output anything before sending the headers. However this plays well with the code I posted because that code will capture all the output and send it after the header is sent.

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

I updated the original code to have the header, I had it in the more complex class one I posted later. But if you add that in it should get rid of the need to manually parse the JSON.

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

One last thing I should mention I do is check if I got JSON back or text, you could still get text in the event that some error occurs before the output buffering is started.

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

There are 2 ways to do this.

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

If Data is a string that needs to be parsed

$.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的标题,那么它会更简单

Or if you have the header and its always JSON, then its a bit simpler

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

希望有帮助!

UPDATE2

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

Because this topic comes up a lot, I put a modified version of the above code on my GitHub you can find it here.

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

这篇关于您如何从AJAX调用的PHP文件中回显SQL SELECT语句?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆