专业编程培训机构——完成蜕变以后轻松拿高薪
电话+V: 152079-09430 ,欢迎咨询php中语句相同为什么有一个会出错|PHP 中的魔术方法详解(二)D1100F0D-34CE-460f-8596-01D4BD6A8C27,[python实用课程],[C++单片机原理],[C#网站搭建],[Nodejs小程序开发],[ios游戏开发],[安卓游戏开发],[教会用大脑用想法赚钱实现阶层跨越]
一、php中语句相同为什么有一个会出错
错误一:Parseerror:syntaxerror,unexpected…
这种错误是PHP解析器在解析时遇到了语法错误,直译为:
解析错误:语法错误,意料之外的…
通常是我们在写代码时,语法格式不对,比如:每一条语句都应当以英文分号结束,如果不写分号,或打成了中文分号,就会报这样的错误。这个错误还会在很多语法不正确的地方报错出现。
错误二:Fatalerror:UncaughtError:Calltoundefinedfunction…
代码在执行时遇到了致命错误,直译为:
致命错误:未捕获错误:调用了未定义的函数…
遇到这个错误其实非常好解决,因为这个提示非常明显,就是看后面报错在第几行,找到这一行,仔细查看这一行中所使用的函数名字是否写错。解决思路:既然提示调用了未定义的函数,就是说函数名无法识别,那肯定是写错函数名或自定义函数真的没定义。
错误三:Notice:Arraytostringconversionin…
这个错误是初学者最容易遇到的,只是一个提示错误,级别非常低,不影响整个代码的执行。出现Parseerror或Fatalerror时PHP程序会中断执行。
错误提示可以理解为提示:数组在第…行转换成字符串
一般是由echo后面输出一个数组时导致的,也可能是数组作为字符串进行拼接运算时导致的。因为PHP是弱类型编程语言,在运算时会自动根据环境需要转换数据类型。解决办法就是找到提示的那一行,将数组提前处理好以后再进行字符串运算即可。
错误四:Parseerror:syntaxerror,unexpected‘1’(T_LNUMBER),expectingvariable…
当出现PHP无法解析的语法错误时会提示这个,unexpected是意料之外的…,后面还有提示expecting是指希望出现…。一般在变量名、函数名等取名不符合命名语法规范时会报这个错。解决办法就是仔细看报错的行命名是否正确。
错误五:Warning:mysqli_fetch_assoc()expectsparameter1tobemysqli_result,booleangiven…
这个错误是一个警告错误,也不影响程序的执行。通常出现在数据库读取结果集数据时,初学者比较难找到错误的解决办法,因为根据无法通过提示所在行找出错误。
直译为:
警告:mysqli_fetch_assoc函数期望参数1是mysqli的结果集,但是给了一个布尔值。
也就是说当我们写好SQL语句从数据库读取数据时,本身应该返回结果集,再给结果集中读取数据。但是,结果集却是一个布尔值,所以反推出极有可能是SQL语句写错了,导致执行出错,结果集就成了执行结果false。
解决办法:仔细检查SQL语句,最好是将拼接好的SQL语句输出出来看看,确认没问题再提交到服务器执行。
错误六:Notice:Undefinedvariable:…
直译为:提示:未定义变量a
当使用了一个未定义的变量时,会报这个错,只需要仔细检查变量的定义或拼写正确即可解决。
错误七:Notice:Undefinedindex:usernamein…
直译为:提示:未定义的索引:username
通常在使用了一个未定义的数组元素时会出现,PHP中有一种特殊的关联数组,可以使用键名访问值,在提示是也按索引数组的方式提示,所以容易造成初学者误解。解决办法就是仔细查看是不是数组键名是否写错或未定义。
错误八:乱码
当看到网页上显示一段看不懂的符号、乱糟糟的繁体字或问号时,我们称为乱码。这是由于PHP生成HTML代码时的字符集与浏览器默认展示的字符集不相同导致的。
解决办法:
二、php开发会遇到什么问题
php开发会遇到什么问题?
十大php开发常见问题盘点
1、使用MyISAM而不是InnoDB
MyISAM是默认使用的。但是除非你是建立一个非常简单的数据库或者只是实验性的,那么到大多数时候这个选择是错误的。MyISAM不支持外键的约束,这是保证数据完整性的精华所在啊。另外,MyISAM会在添加或者更新数据的时候将整个表锁住,这在以后的扩展性能上会有很大的问题。
2、使用PHP的mysql方法
PHP从一开始就提供了MySQL的函数库。很多程序都依赖于mysql_connect、mysql_query、mysql_fetch_assoc等等。
3、不过滤用户输入
应该是:永远别相信用户的输入。用后端的PHP来校验过滤每一条输入的信息,不要相信Javascript。
4、不使用UTF-8
UTF-8解决了很多国际化的问题。虽然PHP6才能比较完美的解决这个问题,但是也不妨碍你将MySQL的字符集设置为UTF-8。
5、该用SQL的地方使用PHP
如果你刚接触MySQL,有时候解决问题的时候可能会先考虑使用你熟悉的语言来解决。这样就可能造成一些浪费和性能比较差的情况。比如:计算平均值的时候不适用MySQL原生的AVG()方法,而是用PHP将所有值循环一遍然后累加计算平均值。
php开发中遇到的难点有哪些_十大php开发常见问题盘点
6、不优化查询
99%的PHP性能问题都是数据库造成的,一条糟糕的SQL语句可能让你的整个程序都非常慢。MySQL的EXPLAINstatement,QueryProfiler,manyothertools的这些工具可以帮你找出那些调皮的SELECT。
7、使用错误的数据类型
MySQL提供一系列数字、字符串、时间等的数据类型。如果你想存储日期,那么就是用DATE或者DATETIME类型,使用整形或者字符串会让事情更加复杂。
8、在SELECT查询中使用*
不要使用*在表中返回所有的字段,这会非常的慢。你只需要取出你需要的数据字段。如果你需要取出所有的字段,那么可能你的表需要更改了。
9、索引不足或者过度索引
一般来说,应该索引出现在SELECT语句中WHERE后面所有的字段。
10、不备份
也许不常发生,但是数据库损毁,硬盘坏了、服务停止等等,这些都会对数据造成灾难性的破坏。所以你一定要确保自动备份数据或者保存副本。
PHP中的魔术方法详解(二)
作用:__toString()方法用于一个类被当成字符串时应怎样回应。例如`echo$obj;`应该显示些什么。
注意:
此方法必须返回一个字符串,否则将发出一条`E_RECOVERABLE_ERROR`级别的致命错误。
警告:
不能在__toString()方法中抛出异常。这么做会导致致命错误。
代码:
classPerson
{
public$sex;
public$name;
public$age;
publicfunction__construct($name="",$age=25,$sex='男')
{
$this->name=$name;
$this->age=$age;
$this->sex=$sex;
}
publicfunction__toString()
{
return'gogogo';
}
}
$person=newPerson('小明');//初始赋值
echo$person;
结果:
gogogo
那么如果类中没有__toString()这个魔术方法运行会发生什么呢?让我们来测试下:
代码:
classPerson
{
public$sex;
public$name;
public$age;
publicfunction__construct($name="",$age=25,$sex='男')
{
$this->name=$name;
$this->age=$age;
$this->sex=$sex;
}
}
$person=newPerson('小明');//初始赋值
echo$person;
结果:
Catchablefatalerror:ObjectofclassPersoncouldnotbeconvertedtostringinD:\\phpStudy\\WWW\\test\\index.phponline18
很明显,页面报了一个致命错误,这是语法所不允许的。
二、__invoke(),调用函数的方式调用一个对象时的回应方法作用:
当尝试以调用函数的方式调用一个对象时,__invoke()方法会被自动调用。
注意:
本特性只在PHP5.3.0及以上版本有效。
直接上代码:
classPerson
{
public$sex;
public$name;
public$age;
publicfunction__construct($name="",$age=25,$sex='男')
{
$this->name=$name;
$this->age=$age;
$this->sex=$sex;
}
publicfunction__invoke(){
echo'这可是一个对象哦';
}
}
$person=newPerson('小明');//初始赋值
$person();
查看运行结果:
这可是一个对象哦
当然,如果你执意要将对象当函数方法使用,那么会得到下面结果:
Fatalerror:FunctionnamemustbeastringinD:\\phpStudy\\WWW\\test\\index.phponline18
三、__set_state(),调用var_export()导出类时,此静态方法会被调用。作用:
自PHP5.1.0起,当调用var_export()导出类时,此静态方法会被自动调用。
参数:
本方法的唯一参数是一个数组,其中包含按array(‘property’=>value,…)格式排列的类属性。
下面我们先来看看在没有加__set_state()情况按下,代码及运行结果如何:
上代码:
classPerson
{
public$sex;
public$name;
public$age;
publicfunction__construct($name="",$age=25,$sex='男')
{
$this->name=$name;
$this->age=$age;
$this->sex=$sex;
}
}
$person=newPerson('小明');//初始赋值
var_export($person);
看结果:
Person::__set_state(array('sex'=>'男','name'=>'小明','age'=>25,))
很明显,将对象中的属性都打印出来了
加了__set_state()之后:
继续上代码:
classPerson
{
public$sex;
public$name;
public$age;
publicfunction__construct($name="",$age=25,$sex='男')
{
$this->name=$name;
$this->age=$age;
$this->sex=$sex;
}
publicstaticfunction__set_state($an_array)
{
$a=newPerson();
$a->name=$an_array['name'];
return$a;
}
}
$person=newPerson('小明');//初始赋值
$person->name='小红';
var_export($person);
继续看结果:
Person::__set_state(array('sex'=>'男','name'=>'小红','age'=>25,))
四、__clone(),当对象复制完成时调用在多数情况下,我们并不需要完全复制一个对象来获得其中属性。但有一个情况下确实需要:如果你有一个GTK窗口对象,该对象持有窗口相关的资源。你可能会想复制一个新的窗口,保持所有属性与原来的窗口相同,但必须是一个新的对象(因为如果不是新的对象,那么一个窗口中的改变就会影响到另一个窗口)。还有一种情况:如果对象A中保存着对象B的引用,当你复制对象A时,你想其中使用的对象不再是对象B而是B的一个副本,那么你必须得到对象A的一个副本。
作用:
对象复制可以通过clone关键字来完成(如果可能,这将调用对象的__clone()方法)。对象中的__clone()方法不能被直接调用。
语法:
$copy_of_object=clone$object;
注意:
当对象被复制后,PHP5会对对象的所有属性执行一个浅复制(shallowcopy)。所有的引用属性仍然会是一个指向原来的变量的引用。
当复制完成时,如果定义了__clone()方法,则新创建的对象(复制生成的对象)中的__clone()方法会被调用,可用于修改属性的值(如果有必要的话)。
看代码:
classPerson
{
public$sex;
public$name;
public$age;
publicfunction__construct($name="",$age=25,$sex='男')
{
$this->name=$name;
$this->age=$age;
$this->sex=$sex;
}
publicfunction__clone()
{
echo__METHOD__."你正在克隆对象
";
}
}
$person=newPerson('小明');//初始赋值
$person2=clone$person;
var_dump('persion1:');
var_dump($person);
echo'
';
var_dump('persion2:');
var_dump($person2);
看结果:
Person::__clone你正在克隆对象
string(9)"persion1:"object(Person)#1(3){["sex"]=>string(3)"男"["name"]=>string(6)"小明"["age"]=>int(25)}
string(9)"persion2:"object(Person)#2(3){["sex"]=>string(3)"男"["name"]=>string(6)"小明"["age"]=>int(25)}
克隆成功。
五、__autoload(),尝试加载未定义的类作用:
你可以通过定义这个函数来启用类的自动加载。
在魔术函数方法出现以前,如果你要在一个程序文件中实例化100个对象,那么你必须用include或者require包含进来100个类文件,或者你把这100个类定义在同一个类文件中——相信这个文件一定会非常大,然后你就痛苦了。
但是有了方法,以后就不必为此大伤脑筋了,这个类会在你实例化对象之前自动加载制定的文件。
还是通过例子来看看吧:
先看看以往的方式:
/**
*文件non_autoload.php
*/
require_once('project/class/A.php');
require_once('project/class/B.php');
require_once('project/class/C.php');
if(条件A){
$a=newA();
$b=newB();
$c=newC();
//…业务逻辑
}elseif(条件B){
$a=newA();
$b=newB();
//…业务逻辑
}
看到了吗?不用100个,只是3个看起来就有点烦了。而且这样就会有一个问题:如果脚本执行“条件B”这个分支时,C.php这个文件其实没有必要包含。因为,任何一个被包含的文件,无论是否使用,均会被php引擎编译。如果不使用,却被编译,这样可以被视作一种资源浪费。更进一步,如果C.php包含了D.php,D.php包含了E.php。并且大部分情况都执行“条件B”分支,那么就会浪费一部分资源去编译C.php,D.php,E.php三个“无用”的文件。
那么如果使用方式呢?
/**
*文件autoload_demo.php
*/
function__autoload($className){
$filePath=“project/class/{$className}.php”;
if(is_readable($filePath)){
require($filePath);
}
}
if(条件A){
$a=newA();
$b=newB();
$c=newC();
//…业务逻辑
}elseif(条件B){
$a=newA();
$b=newB();
//…业务逻辑
}
ok,不论效率怎么用,最起码界面看起来舒服多了,没有太多冗余的代。
再来看看这里的效率如何,我们分析下:
当php引擎第一次使用类A,但是找不到时,会自动调用方法,并将类名“A”作为参数传入。所以,我们在中需要的做的就是根据类名,找到相应的文件,并包含进来,如果我们的方法也找不到,那么php引擎就会报错了。
注意:
这里可以只用require,因为一旦包含进来后,php引擎再遇到类A时,将不会调用__autoload,而是直接使用内存中的类A,不会导致多次包含。
扩展:
其实php发展到今天,已经有将`spl_autoload_register`—注册给定的函数作为__autoload的实现了,但是这个不在啊本文讲解之内,有兴趣可以自行看手册。
六、__debugInfo(),打印所需调试信息注意:
该方法在PHP5.6.0及其以上版本才可以用,如果你发现使用无效或者报错,请查看啊你的版本。
看代码:
classC{
private$prop;
publicfunction__construct($val){
$this->prop=$val;
}
/**
*@returnarray
*/
publicfunction__debugInfo(){
return[
'propSquared'=>$this->prop**2,
];
}
}
var_dump(newC(42));
结果:
object(C)#1(1){["propSquared"]=>int(1764)}
再次注意:
这里的`**`是乘方的意思,也是在PHP5.6.0及其以上才可以使用,详情请查看PHP手册
【FUTURE PROGRAMMING COURSE】尊享对接老板
电话+V: 152079-09430
机构由一批拥有10年以上开发管理经验,且来自互联网或研究机构的IT精英组成,负责研究、开发教学模式和课程内容。公司具有完善的课程研发体系,一直走在整个行业发展的前端,在行业内竖立起了良好的品质口碑。