读书笔记:深入理解PHP高级技巧、面向对象、核心技术 二 (19.1.21-19.2.10)

设计模式

1.单例模式:创建性模式,会限制应用程序,使其职能创建某一特定类类型的一个单一的实例

       我们可以使用一个静态属性来保证对于一个特定的类来说只存在一个单一的实例    

class Sc{
 static private $_instance=NULL;
 static function getInstance(){
   if(self::$_instance==NULL){
     self::$_instance=new SC();
    }
return self::$_instance;
  }
}

   因为属性是静态的,它会被类的所有实例共享,不能使用构造函数,但是这里也有一个例外,如果使用new或者clone去创建这个类的一个新的对象,那么我们将会得到多个实例,这就破坏了单例模式的限制,防止这个情况发生的一个技巧就是创建一个私有的构造函数,但是这样使用会报错(因为类的构造函数是私有的,因此我们不能使用new去创建这个类型的一个对象),使用单例模式的一个比较好的场景就是创建一个全局的对象

2.工厂模式:创建性模式,可能被用于创建多个不同类型的类的多个对象,而单例模式会创建和管理一个单独的类型的单一对象

           场景: 并不能确定生成对象的时候其确切的对象类型,只有在运行的时候才确定

           工厂模式通常通过一个静态方法实现,一般下该情况被命名为Create()、factory()、factoryMethod()或者createInstance()

           例如:

static function Create($type){
   switch($type){
     case 'r':
   return new R();
}
}

3.组合模式:属于结构型模式,           

4策略模式:属于行为列模式,用来说明一个应用是如何运作的,当我们使用的类比较简单,但是又相互不关联,只是在特定行为上有所差异的场景,策略模式就会十分有用

使用既有的类

1.捕获异常:异常处理比条件判断好的一点在于,它能进一步的将程序的功能和逻辑与错误处理分离开来,进一步,多重错误可以无须使用多层嵌套的条件语句就能得到处理

try{
}catch(exception $e){
  echo $e->getMessage();
}

例子:

<?php
 class W{
 private $_fp=null;
	 function __construct($file){
	 	if(!file_exists($file)){
	 		throw new Exception('this file does not exist');
	 	}
		if(!$this->_fp=@fopen($file,'w')){
			throw new Exception('not open the file');
		}
	 }
		function write($data){
			if(@!fwrite($this->_fp,$data."\n")){
				throw new Exception('not write the file');
			}
		}
		function __destruct(){
			if($this->_fp){
				fclose($this->_fp);
				$this->_fp=null;
			}
		}
	 
 }
 
try{
	 $fp=new W('data.txt');
	 $fp->write('this is a line of data.1');
	 unset($fp);
}catch(Exception $e){
	echo $e->getMessage();
}
?>

   Exception类只有构造函数与__toString方法时可以覆盖的,其他方法都被定义为final类型

2.使用PDO:

1>.连接PDO    $pdo=new PDO('dns','name','pwd');    dns指明一下的多条信息  需要使用的数据库驱动、数据库名、主机名、端口号,driver:name=val;name2=val2;

$pdo=new PDO('mysql:dbname=test;host=localhost','username','pwd');
unset($pdo)/$pdo=null

2>.简单操作:对于不返回结果的查询:insert,update,delete使用exec()方法

$q=delete from tablename";
$num=$pdo->exec($q);

exec()方法会返回该查询影响到的行数,但是如果只是执行insert查询并需要知道动态生成的主键数,需要调用laseInsertId(),等价于mysqli_insert_id();

最后执行简单查询需要了解如何防止SQL注入,使用MYSQL优化扩展时。可以通过调用mysqli_real_escape_string()处理,相应的需要调用PDO的qute()方法

$data=mysqli_real_escape_string($dbc,$datas);
//pdo
$data=$pdo->quote($dates);
$pdo->exec("insert into tablename (column1)values ($data)");

3>select:对于不返回记录的查询通过exec()执行,而那些需要返回运行结果的查询需要调用query()

$result=$pdo->query($q);
$result->rowCount();//返回了多少条记录,与调用mysqli_num_rows()等价

  一旦执行了返回结果的查询,我们可以使用PDOStatament类的对象(如$results)的fetch()方法,首先需要设定PHP读取记录的方式,通过setFetchMode(常数),常数的值为:                                     

$results=$pdo->query();
$results=setFetchMode(PDO::FETCH_NUM);
while($row=$results->fetch()){
//Use $row[0] for theis
}
//也可以不适用fetch直接读取结果
foreach($pod->query($q) as $row){
  //Use $row
}

还有一种做法是将返回的记录直接转换为具体类的对象

class User{

private $id;
private $username;
public getUsername(){
 return $this->username;
}
}

$resulets=$pdo->query('select id,username from users');
$resulets->setFetchMode(PDO::FETCH_CLASS,'User');
while($row=$results->fetch()){
 echo $row->getUsername();
}

  PHP直接将返回的列名与类的属性的名字进行匹配,如果没有属性名与列名想匹配,PHP会创建于列名相同的PUBLIC属性,默认情况,PHP会将数据表中的列值映射到类属性之后再调用类的构造函数,这种行为可以通过更改setFetchMode()调用

4>使用预定义语句:查询语句和具体数据分开传送,更高的执行效率,因为数据与查询分开传送,就不需要预防SQL注入攻击

   首先调用prepare()方法,将查询语句作为参数传递给该方法,动态数据用占位符(?)来代替,接下来调用execute()方法,其参数为动态数据组成的数组:

$stmt=$pdo->prepare('select * from where email=? and pass = SHA1(?)');

$stmt->execute(array('ne.com','123'));

  还有一种更加显式的代替符号成为‘具名占位符’,如上 email=:email and pass=SHA1(:pass),  $stmt->execute(array(':email'=>'me.com',':pass'=>'mypass'))

 

 

 PHP网络编程

1.访问其他网站

   fopen既可以用来打开文件,也可以用来打开网页,因为网页其实也不过是保存在其他服务器上的文件而已,只是fopen只能用读的方式打开,但是必须在一文件夹后加一个反斜杠,因为fopen()函数不支持重定向

2.PHP socket编程:fsockopen($url,$port,$error_number,$error_string,$timeout);

   使用fsockopen()函数与使用fopen()一样会得到一个文件指针,参数:error_number 一个存放错误编号的变量,error_string 一个存放错误信息字符串的变量和timeout 超时等待时间,port端口 21 FTP,22 SSH,80WEB

   一旦文件成功打开,就可以使用fwrite(),fgets()函数,这样可以进一步处理数据

<?php
$url='http://www.baidu.com/index.php?week=1#domo';
$read=parse_url($url);
var_dump($read);
?>

   

  parse_url()可以将url通过其结构分解成一个关联数组,scheme协议号,host:主机名,port:端口号,path文件路径,query查询参数

3.cUrl:

 

    其中curl_getinfo()函数返回关于事务信息的数组,该函数只能在关闭连接之前调用,cUrl工具还能够传送、接受cookie,处理文件上传,通过SSL连接工作,甚至处理FTP文件,可以通过curl_errno()和curl_error()来获取错误码和出错信息

 

PHP与服务器

1文件压缩:  借助于zlib库,PHP也可以实现文件压缩功能 zlib的大部分函数与标准文件处理函数相似,如fopen()、fwrite()、fclose() 

首先,打开一个文件,并指明打开模式:

 $fp=gzopen('filename.gz','mode');   在模式符之后可以添加标识文件压缩程度的数字,该数字从1到9(最大压缩程度),也可以在模式符之后添加f、h和b标识进一步修饰文件打开模式

例如:$fp=gzopen("123.gz",'w9');   $gzwrite($fp,"$value");   gzclose($fp);  (我们可以使用zlib库和php zip扩展来创建ZIP压缩包)

2.创建cron任务:crontab格式规定每一样都包括由空格符隔开的6个域,前五个域依次标识:分钟、小时、天、月、一周的第几天(0-6,0表示周日),可以将执行日期设定为每月的某一天(1-31)或者每周的某一天(周日至周六)、后者是日期无关

   也可以使用连字符设定范围(月的域中1-6表示该任务在一年的1-6个月份都会执行),也可以使用逗号分隔符(1,3,5表示周一、周三、周五),第六个域表示要执行的任务,

*/5 * * * * /usr/bin/curl -o temp.txt http://www.jb51.net/myscript.php

例子是使用CURL访问URL来每5分执行PHP脚本。Curl默认在标准输出显示输出。使用”curl -o”选项,你也可以把脚本的输出转储到临时文件。

-e  编辑该用户的计时器设置。
-l  列出该用户的计时器设置。
-r  删除该用户的计时器设置。
-u<用户名称>  指定要设定计时器的用户名称。

3.MCrypt:

   PHP自带的数据加密和解密,在不储存到数据库里不借助数据加密和解密的时候使用。在linux下则需要安装对应的mcrypt.so扩展,例如会话数据通常作为普通文本保存在已有文件中,也就是说,会话数据几乎没有安全保护,使用MCrypt,我们可以加密保存的数据添加保护

              

                                                                    

猜你喜欢

转载自blog.csdn.net/ligupeng7929/article/details/86570384