PHP 中使用ajax时一些常见错误总结整理

 更新时间:2017年7月6日 23:49  点击:1361
本文介绍了PHP 中使用ajax时一些常见错误总结整理,非常实用,有兴趣的同学可以看看

PHP作为后端时,前端js使用ajax技术进行相互信息传送时,经常会出错误,对于新手来说有些手足无措。总结错误、经验,以后随时回顾。

第一个问题,当前端无错误的情况下,页面调试也显示没有问题,但是ajax获取不到后端php文件发送过来的信息:

前端代码如下:

 

 代码如下复制代码

$.ajax({

  url:Ƈ.php',//目的php文件

  data:{"age":12,"name":'zh'},//传送的数据

  type:‘post',//方式post/get

  dataType:'json',//数据传送格式

  success:function(response)

  {

  console.log(response);

  },

  error:function(response)

  {

  console.log(response);

  console.log("错误");

  }

});

 

php后端代码如下:

 

 代码如下复制代码

$postAge=$_POST['age'];

$postName=$_POST['name'];

echo$postAge;

echo$postName;

 

页面出现后,F12调试查看如下所示:

状态码都没问题,status是200,responseReady是4,说明在html发送给php文件信息过程是没有问题的。而且php也返回了信息。可是为什么程序走了error而没有走success呢?

这时需要小心!由于php后端多个echo没有把数据整理为json格式。也就是说php返回的是一个字符串不是json格式的数据。有人说加上json_encode()呢?这样也是不行的,因为json_encode()的函数作用没搞清,百度仔细看下。json_encode()与json_decode()是一对。

json_encode(json),把json整理为json格式的数据。在上例中,就算php后端代码改写为:echo   json_encode(postAge);和echojsonencode(postName);也是不对的。因为这样仅仅是把单个postAge和postName整理为了json格式,但是由于是2个返回,既是2个response,在浏览器调试页面也可以看到1个post回来2个response。这样导致2个json格式的数据返回给前端是就不再是json格式的数据(我理解为json污染,方便理解)。也就是单个数据是json格式但是多个json格式数据“胡乱”结合在一起不按照json格式合并在一起就会产生“污染”。导致整体数据格式混乱无法被识别,这种情况者数据处理和传输时随时都见得到。

json_decode(json,true/false)函数是把json整理为数组或者object(理解为类)。true是强制装换为(关联)数组,false是默认的会转换为object形式的数据。

回到本文提出的例子上。

既然传送回来的数据不再是json格式的数据,那么就是dataType的问题了。

dataType是告诉浏览器检查传送的数据格式。如果不写,浏览器不会去检查数据格式,写了就一定检查而且必须满足格式要求。本例中,由于写了为json格式,但是传回来时不是json格式,所以浏览器认为传输过程中出现了错误,所以走了error而没有走success。

这时最好的方式是修改php代码,将echo的内容改为一个数组,用数组的信形式把整体数据整理为json格式进行传送(json_encode),避免发生错误。

当然也可以使用另一种方法,类似作弊的方法,直接注释掉(或者不写)dataType,这样浏览器就不会去检查数据的形式而是根据数据的形式智能的判断,类似蒙混过关。

 以下是dataType的W3school解释:

这里写图片描述

值得注意的是,后端php文件中多个echo输出后,数据返回确是一起返回的,既是修改正确后,前端得到的数据是2个数据合为一个字符串的形式数据。本例子中得到的数据是12zh。

当然还有很多细节问题了,比如php后端只能用echo或者die(),不能用return,这是因为return是只在服务器端中返回数据使用,而echo是打印数据,将数据从服务器端打印出来,给前端。return只能在服务器端,或者前端单一的返回。而die()的强大就不提了,直接终止后端php程序的形式返回数据。

还有比如在$,ajax({});中每一行既是一个参数,参数之间是逗号隔开,多个数据是在{}内,隔开是用逗号等等。

小编给大家推荐的这篇文章介绍了浅谈PHP的反射API的教程,非常实用,有兴趣的同学快来看看吧

PHP的反射API,即在PHP运行状态下,通过分析PHP程序,可以导出对象所属的类,方法,属性,参数等信息。

如何使用反射API

示例代码 Person.php

Person类,包含一个成员变量和三个成员方法

获取$student对象的方法和属性列表

ReflectionClass类报告了一个类的有关信息

输出结果为:name say __set __get

也可以用class函数,获取对象属性的关联数组的信息

通过class()函数获取类的信息

打印结果:

通过这个反射API,可以做hook实现插件功能,动态代理等。

网上找的动态代理示例

小编推荐的这篇文章介绍了Python实现 多进程导入CSV数据到 MySQL的教程,非常实用,有兴趣的同学快来看看吧

前段时间帮同事处理了一个把 CSV 数据导入到 MySQL 的需求。两个很大的 CSV 文件, 分别有 3GB、2100 万条记录和  7GB、3500 万条记录。对于这个量级的数据,用简单的单进程/单线程导入  会耗时很久,最终用了多进程的方式来实现。具体过程不赘述,记录一下几个要点:

  1. 批量插入而不是逐条插入

  2. 为了加快插入速度,先不要建索引

  3. 生产者和消费者模型,主进程读文件,多个 worker 进程执行插入

  4. 注意控制 worker 的数量,避免对 MySQL 造成太大的压力

  5. 注意处理脏数据导致的异常

  6. 原始数据是 GBK 编码,所以还要注意转换成 UTF-8

  7. 用 click 封装命令行工具

具体的代码实现如下:

 

 代码如下复制代码

#!/usr/bin/env python

# -*- coding: utf-8 -*-

 

importcodecs

importcsv

importlogging

importmultiprocessing

importos

importwarnings

 

importclick

importMySQLdb

importsqlalchemy

 

warnings.filterwarnings('ignore', category=MySQLdb.Warning)

 

# 批量插入的记录数量

BATCH=5000

 

DB_URI='mysql://root@localhost:3306/example?charset=utf8'

 

engine=sqlalchemy.create_engine(DB_URI)

 

 

defget_table_cols(table):

  sql='SELECT * FROM `{table}` LIMIT 0'.format(table=table)

  res=engine.execute(sql)

  returnres.keys()

 

 

definsert_many(table, cols, rows, cursor):

  sql='INSERT INTO `{table}` ({cols}) VALUES ({marks})'.format(

      table=table,

      cols=', '.join(cols),

      marks=', '.join(['%s']*len(cols)))

  cursor.execute(sql,*rows)

  logging.info('process %s inserted %s rows into table %s', os.getpid(),len(rows), table)

 

 

definsert_worker(table, cols, queue):

  rows=[]

  # 每个子进程创建自己的 engine 对象

  cursor=sqlalchemy.create_engine(DB_URI)

  whileTrue:

    row=queue.get()

    ifrowisNone:

      ifrows:

        insert_many(table, cols, rows, cursor)

      break

 

    rows.append(row)

    iflen(rows)==BATCH:

      insert_many(table, cols, rows, cursor)

      rows=[]

 

 

definsert_parallel(table, reader, w=10):

  cols=get_table_cols(table)

 

  # 数据队列,主进程读文件并往里写数据,worker 进程从队列读数据

  # 注意一下控制队列的大小,避免消费太慢导致堆积太多数据,占用过多内存

  queue=multiprocessing.Queue(maxsize=w*BATCH*2)

  workers=[]

  foriinrange(w):

    p=multiprocessing.Process(target=insert_worker, args=(table, cols, queue))

    p.start()

    workers.append(p)

    logging.info('starting # %s worker process, pid: %s...', i+1, p.pid)

 

  dirty_data_file='./{}_dirty_rows.csv'.format(table)

  xf=open(dirty_data_file,'w')

  writer=csv.writer(xf, delimiter=reader.dialect.delimiter)

 

  forlineinreader:

    # 记录并跳过脏数据: 键值数量不一致

    iflen(line) !=len(cols):

      writer.writerow(line)

      continue

 

    # 把 None 值替换为 'NULL'

    clean_line=[Noneifx=='NULL'elsexforxinline]

 

    # 往队列里写数据

    queue.put(tuple(clean_line))

    ifreader.line_num%500000==0:

      logging.info('put %s tasks into queue.', reader.line_num)

 

  xf.close()

 

  # 给每个 worker 发送任务结束的信号

  logging.info('send close signal to worker processes')

  foriinrange(w):

    queue.put(None)

 

  forpinworkers:

    p.join()

 

 

defconvert_file_to_utf8(f, rv_file=None):

  ifnotrv_file:

    name, ext=os.path.splitext(f)

    ifisinstance(name,unicode):

      name=name.encode('utf8')

    rv_file='{}_utf8{}'.format(name, ext)

  logging.info('start to process file %s', f)

  withopen(f) as infd:

    withopen(rv_file,'w') as outfd:

      lines=[]

      loop=0

      chunck=200000

      first_line=infd.readline().strip(codecs.BOM_UTF8).strip()+'\n'

      lines.append(first_line)

      forlineininfd:

        clean_line=line.decode('gb18030').encode('utf8')

        clean_line=clean_line.rstrip()+'\n'

        lines.append(clean_line)

        iflen(lines)==chunck:

          outfd.writelines(lines)

          lines=[]

          loop+=1

          logging.info('processed %s lines.', loop*chunck)

 

      outfd.writelines(lines)

      logging.info('processed %s lines.', loop*chunck+len(lines))

 

 

@click.group()

defcli():

  logging.basicConfig(level=logging.INFO,

            format='%(asctime)s - %(levelname)s - %(name)s - %(message)s')

 

 

@cli.command('gbk_to_utf8')

@click.argument('f')

defconvert_gbk_to_utf8(f):

  convert_file_to_utf8(f)

 

 

@cli.command('load')

@click.option('-t','--table', required=True,help='表名')

@click.option('-i','--filename', required=True,help='输入文件')

@click.option('-w','--workers', default=10,help='worker 数量,默认 10')

defload_fac_day_pro_nos_sal_table(table, filename, workers):

  withopen(filename) as fd:

    fd.readline() # skip header

    reader=csv.reader(fd)

    insert_parallel(table, reader, w=workers)

 

 

if__name__=='__main__':

  cli()

 

小编给大家推荐的这篇文章介绍了简单谈谈PHP中的trait的教程,非常实用,有兴趣的同学快来看看吧

前言

之前的一个同事换工作,在面试被问到了 PHP 的 trait 。因为没用过, 所以没答好,我大概是用过几次的,想了想整理了以下的总结。

trait

trait 是在一些类(Class)的应该具备的特定的属性或方法,而同父级的另外一些类应该避免包含这些属性和方法情况下使用的.

当然, 这也和开发者对类的抽象能力有关, 有些抽象能力好的, 可以减少对 trait 的使用 但是这种情况应该是无法避免的 不然 trait 出现就毫无意义了.

还有一种情况, 就是使用 trait 的时候, 可以起到的约束开发者的作用, 提醒开发者注意需要在开发的过程中调用 trait 的某些属性和方法.

同事则提出了一个好问题, 接口(interface) 不也是这个作用么?

不急, 让我们先看个例子:

比如你要收集网站上各类数据, 开发了 Spider 类. Spider有个方法叫request()负责请求.

 

 代码如下 复制代码

<?phpnamespaceXWSoul\Network;

classSpider

{

 publicfunctionrequest($url)

 {

 //do sth.

 }

}

 

但是采集数据的过程中, 有些网站对蜘蛛敏感有些则不. 对于敏感的网站, 我们给出了一个使用代理的解决方案. 但是使用代理是会影响抓取速度的. 这就产生了 Spider 的子类有些需要用代理, 而能不用代理则尽量不用的情况.

于是这个时候我们新增了一个 trait Proxy:

 

 代码如下 复制代码

<?phpnamespaceXWSoul\Network;

trait Proxy

{

 

 protected$isProxy= false;

 

 publicfunctionuseProxy($proxy)

 {

 //do sth proxy setups.

 $this->isProxy = true;

 return$this;

 }

 

 publicfunctionrequest($url)

 {

 if(!$this->isProxy) {

  thrownewException("Please using proxy.");

 }

 //do sth.

 returnparent::request($url);

 }

}

 

trait 重写了 Spider 的request()方法, 限定了在没有调用代理的情况下调用会抛出异常.

回到之前的问题, trait 这样的用法和 接口(interface) 有什么区别?

接口的约束是前置的是定义初始就必须实现的, 他可以约束方法的实现却无法约束方法的调用, trait 是一种后置的调用, 他已经实现了方法,  关键的是, 他只对调用了自身的类产生约束(废话一句), 而对没有调用自身的类不产生影响(再一句废话), 同时他是可复用的, 而且没有破坏  Spider 类自身的实现增加, Spider 还是那个 Spider.

我想 trait 的用法再这里已经很有效了吧.

后话

有人可能决定 另外实现一个 request 比如叫, proxyRequst 不就完了么? 你说的好有道理&hellip;然是如果我使用了不一样的 代理具体对请求上有细节差异怎么办呢? 在代码里不停的 if if if 么? trait 如此清爽的方案 为何要放弃呢?

[!--infotagslink--]

相关文章

  • Ecshop提示Only variables should be passed by reference in错误

    在安装好ecshop软件之后我们打开首页时提示Only variables should be passed by reference in错误了,碰到这个问题是什么原因呢?下面我们就一起来看看解决办法吧。...2016-11-25
  • 409错误是什么 http 409错误怎么解决

    409错误是什么?http 409错误怎么解决呢?不少站长在遇到这个错误代码之后都一筹莫展,本次一聚教程网为大家带来了详细的说明,快来看看吧。 409错误是什么: HTTP 40...2017-01-22
  • 414错误是什么 414错误怎么解决

    414错误是HTTP协议状态码中的一种,很多都还不知道414错误是什么,以及不知道怎么解决414错误,那么就来看看小编带来的介绍吧。 414错误是什么: HTTP 414错误,(Requ...2017-01-22
  • http 405错误是什么 http 405错误怎么解决

    http 405错误是什么?http 405错误怎么解决?相信很多站长都在找这两个问题的答案,本次小编为大家带来了详细的教程,快来看看吧。 405错误是什么: HTTP 405错误是H...2017-01-22
  • 401错误码代表什么 401错误解决办法

    401是HTTP状态码的一种,属于“请示错误”,表示请求可能出错,已妨碍了服务器对请求的处理。具体的401错误是指:未授权,请求要求进行身份验证。登录后,服务器可能会返回对页面...2017-01-22
  • http 402错误是什么 http 402简介

    http 402错误是什么?402错误较为少见,一般不轻易出现,下面小编就来告诉大家402错误是什么吧。 HTTP 402错误是HTTP状态码的一种,表示“要求付费”; 所求的...2017-01-22
  • 411错误是什么 411错误怎么解决

    411错误是HTTP协议状态码的一种,很多人都还不知道411错误是什么,本次一聚教程网将为大家进行解答,并且告诉大家411错误怎么解决。 411错误是什么: HTTP 411错误,(Lengt...2017-01-22
  • apache网站提示503错误解决办法

    Apache status 503 的原因大致有如下几种情况 : 1、 CPU 负载过高,服务器响应不过来,返回503 2、 系统连接数超限,超过MaxVhostClients的上限,返回503 3、 单IP连接数超限,超过M...2016-01-28
  • 404错误是什么 404错误怎么解决

    403错误是网站访问过程中,常见的错误提示。资源不可用,服务器理解客户的请求,但拒绝处理它。通常由于服务器上文件或目录的权限设置导致,比如IIS或者apache设置了访问权限...2017-01-22
  • 403错误是什么 403错误怎么解决

    403错误是HTTP状态码的一种,属于“请示错误”,表示服务器拒绝请求。如果在搜索引擎尝试抓取您网站上的有效网页时显示此状态代码,那么,这可能是您的服务器或主机拒绝搜索...2017-01-22
  • Bootstrap Table使用整理(二)

    这篇文章主要介绍了Bootstrap Table使用整理(二)的相关资料,需要的朋友可以参考下...2017-06-15
  • 412错误是什么 412错误怎么解决

    412错误是什么?412错误怎么解决?本次一聚教程网将为大家带来详细的介绍,帮助大家全面了解412错误的意思以及解决412错误的方法。 412错误是什么: HTTP 412错误,(Precond...2017-01-22
  • HTTP 408错误是什么 HTTP 408错误解决方法

    相信很多站长都遇到过这样一个问题,访问页面时出现408错误,下面一聚教程网将为大家介绍408错误出现的原因以及408错误的解决办法。 HTTP 408错误出现原因: HTT...2017-01-22
  • 407错误是什么 407错误怎么解决

    407错误是什么?407错误怎么解决?不少站长都遇到过407错误,下面小编将告诉大家如何处理407错误。 407错误是什么: HTTP 407错误是HTTP协议状态码的一种,表示需要代...2017-01-22
  • 406错误是什么 406错误怎么解决

    HTTP 406错误是HTTP协议状态码的一种,表示无法使用请求的内容特性来响应请求的网页。一般是指客户端浏览器不接受所请求页面的 MIME 类型。 而MIME类型是在把输出...2017-01-22
  • 410错误是什么 http 410错误怎么解决

    410错误是HTTP协议状态码的一种,本次一聚教程网将为大家详细介绍HTTP 410错误是什么,以及410错误的解决办法。 410错误是什么: HTTP 410错误是HTTP协议状态码的...2017-01-22
  • HTTP 400错误是什么 HTTP 400错误怎么解决

    每当遇到http错误代码为400,代表客户端发起的请求不符合服务器对请求的某些限制,或者请求本身存在一定的错误,那么HTTP 400错误怎么解决呢?请看下文介绍。 目前400错...2017-01-22
  • PHP Fatal error: Cannot use object of type stdClass as array in错误

    下面一起来看看在php开发中碰到PHP Fatal error: Cannot use object of type stdClass as array in错误问题的解决办法吧。 普通的数组出现如下错误 代码...2016-11-25
  • PHP Curl出现403错误的解决办法

    自己用的小PHP应用,使用curl抓网页下来处理,为了穿墙方便,使用Privoxy作为代理,便于选择哪些网站使用proxy、哪些不用。但今天却遇到了奇怪的问题,访问google baidu这些网站居然都返回403错误,而访问其他的一些网站没事,如果...2014-05-31
  • C#新手常犯的错误汇总

    这篇文章主要介绍了C#新手常犯的错误汇总,对于经验丰富的C#程序员同样具有很好的参考借鉴价值,需要的朋友可以参考下...2020-06-25