标签 - PHP

PHP    2021-06-16 15:34:17    46    0    0

在面向对象的设计中,如何通过很少的设计改变就可以应对设计需求变化,这是设计者极为要关注的问题。为此,我们需要掌握面向对象设计的5大设计原则。
面向对象设计的5大设计原则分别是:

  1. 单一职责原则
  2. 接口隔离原则
  3. 开放-封闭原则
  4. 里氏替换原则
  5. 依赖倒置原则
    这5大原则也是23种类设计模式的基础

单一职责原则

单一职责原则(Single Responsibility Principle,SRP)
一个类被改变的原因不能超过一个,也就是说,一个类只有一个职责,如果职责过多,代码就会臃肿,可读性更差,也更难以维护。

为什么要遵守单一职责原则

1、提高类的可维护性和可读写性
一个类的职责少了,复杂度降低了,代码就少了,可读性也就好了,可维护性自然就高了
2、提高系统的可维护性
系统是由类组成的,每个类的可维护性高,相对来讲整个系统的可维护性就高。当然,前提是系统的架构没有问题。
3、降低变更的风险
一个类的职责越多,变更的可能性就更大,变更带来的风险也就越大

如何遵守单一职责原则

合理的职责分解相同的职责放到一起,不同的职责分解到不同的接口和实现中去

单一职责原则最佳实践

在实际工作中,有一个经常会用到的设计模式,DAO模式,又叫数据访问对象,里面定义了数据库中表的增、删、改、查操作.
按照单一职责原则,为什么不把增、删、改、查分别定义成四种接口?这是因为数据库的表操作,基本上就是这四种类型,不可能变化,所以没有必要分开定义。
反而经常变化的是数据库的表结构,表结构一变,这四种操作都要跟着变。所以通常我们会针对一张表实现一个DAO,一张表就代表一种类型的职责。

遵循单一职责原则代码实例

代码源码

接口隔离原则

接口隔离原则(Interface Segregation Principle,ISP)

1.客户端不应该依赖它不需要的接口
2.类间的依赖关系应该建立在最小的接口上

通俗来讲:使用多个专门的接口比使用单一的总接口要好。

接口如果能够保持粒度够小,就能保证它足够稳定
换而言之,从一个客户类的角度来讲:一个类对另外一个类的依赖性应当是建立在最小接口上的。
过于臃肿的接口是对接口的污染。不应该强迫客户依赖于它们不用的方法。

接口隔离原则与单一职责原则对比

接口隔离原则和单一职责原则非常类似。

单一职责原则要求接口的职责是单一的,而接口隔离原则要求接口尽量细化,它们有异曲同工之妙,都是要让我们的接口功能尽量单一,尽量小。
但是,单一职责原则的着重点是在“职

PHP    2020-03-10 14:20:53    128    0    0

1. 何为OPCode

在计算机科学领域中,操作码(Operation Code, OPCode)被用于描述机器语言指令中,指定要执行某种操作的那部分机器码,构成OPCode的指令格式和规范由处理器的指令规范指定。除了指令本身以外通常还有指令所需要的操作数,可能有的指令不需要显示的操作数。这些操作数可能是寄存器中的值,堆栈中的值,某块内存的值或者IO端口中的值等等。
OPCode在不同的场合中通常具有不同的含义,例如PHP虚拟机(Zend VM)、java虚拟机(JVM)以及一些软件保护虚拟机中的最小操作单元都可以称之为OPCode。
在本节课中,介绍的是Intel 80x86 CPU的OPCode
2. 常用单字节OPCode概览A -- 40~4F
                   opcode                                asm                        using
                     0x40                                  inc eax                 emit(0x40)
                     0x41                                  inc ecx                 emit(0x41)
                     0x42                                  inc edx                 emit(0x42)
                     0x43                                  inc ebx                 emit(0x43)
                     0x44                                  inc esp                 emit(0x44)
                     0x45                                  inc ebp                 emit(0x45)
                     0x46  
PHP    2020-03-10 14:20:06    30    0    0

PHP是一种适用于web开发的动态语言。具体点说,就是一个用C语言实现包含大量组件模块的软件框架。是一个强大的UI框架。

简言之;PHP动态语言执行过程:拿到一段代码后,经过词法解析、语法解析等阶段后,源程序会被翻译成一个个指令(opcodes),然后ZEND虚拟机顺次执行这些指令完成操作。PHP本身是用C实现的,因此最终调用的也是C的函数,实际上,我们可以把PHP看做一个C开发的软件。

一.PHP的设计理念及特点

1、多进程模型:由于PHP是多进程模型,不同请求间互不干涉,这样保证了一个请求挂掉不会对全盘服务造成影响,目前PHP也早支持多线程模型。

2、弱类型语言:和C/C++、JAVA、C#等语言不同,PHP是一种弱类型的语言。一个变量的类型并不是一开始就确定不变的,运行中才会确定并可能发生隐式或显示的类型转换,这种机制的灵活性在web开发中非常方便、高效,具体会在后面PHP变量中详述。

3、引擎(Zend)+组件(ext)的模式降低内部耦合。

4、中间层(sapi )Sapi全称是Server Application Programming Interface 隔绝web server和PHP。

5、语法简单灵活,没有太多规范。缺点导致风格混杂。

二、PHP的四层体系

PHP的核心架构如下图:(我自己根据网上的图有PS了下;比较形象了;www.daokr.com 是我的个人网站;准备运营一个PHP开源项目;之前的www.ikphp.com我是网站长)

PHP从下倒上是一个4层体系:

1、Zend引擎:Zend整体用纯C实现,是PHP的内核部分,他将PHP代码翻译(词法、语法解析等一系列编译过程)为可执行opcode的处理并实现相应的处理方法、实现了基本的数据结构(如:hashtable、OO)、内存分配机制及管理、提供了相应的api方法供外部调用,是一切的核心,所有的外围功能均围绕Zend实现。

2、Extensions:围绕着Zend引擎,extensions通过组件式的方式提供各种基础服务,我们常见的各种内置函数(array系列)、标准库等都是通过extension来实现,用户也可以根据需要实现自己的extension的典型应用)。

3、Sapi:Sapi全称Server Application Programming Interface,也就是服务端应用编程接口,Sapi通过一系

PHP    2019-11-07 19:52:51    16    0    0

实例

计算两个日期间的差值:

<?php
$date1=date_create("1984-01-28");
$date2=date_create("1980-10-15");
$diff=date_diff($date1,$date2);
?>

定义和用法

date_diff() 函数返回两个 DateTime 对象间的差值。

语法

date_diff(datetime1,datetime2,absolute);
参数描述
datetime1必需。规定 DateTime 对象。
datetime2必需。规定 DateTime 对象。
absolute可选。规定布尔值。TRUE 表示间隔/差值必须是正的。默认是 FALSE。

技术细节

返回值:如果成功则返回一个 DateInterval 对象,表示两个日期间的差值。如果失败则返回 FALSE。
PHP 版本:5.3+
PHP    2019-09-16 20:29:18    44    0    0

1、冒泡排序

在要排序的一组数中,对当前还未排好的序列,从前往后对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒。即,每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换。

// 升序
$arr=[1,43,54,62,21,66,32,78,36,76,39];
function bubbleSort($arr)
{  
  $len=count($arr);
  //该层循环控制 需要冒泡的轮数
  for($i=1;$i<$len;$i++)
  { //该层循环用来控制每轮 冒出一个数 需要比较的次数
    for($k=0;$k<$len-$i;$k++)
    {
       if($arr[$k]>$arr[$k+1])
        {
            $tmp=$arr[$k+1];
            $arr[$k+1]=$arr[$k];
            $arr[$k]=$tmp;
        }
    }
  }
  return $arr;
}
// 降序
function bubbleSort($arr)
{  
  $len=count($arr);
  for($i=1;$i<$len;$i++)
  { 
    for($k=0;$k<$len-$i;$k++)
    {
        // 只需要此处大小比较进行替换即可
       if($arr[$k]<$arr[$k+1])
        {
            $tmp=$arr[$k+1];
            $arr[$k+1]=$arr[$k];
            $arr[$k]=$tmp;
        }
    }
  }
  return $arr;
}

2、快速排序

选择一个基准元素,通常选择第一个元素或者最后一个元素。通过一趟扫描,将待排序列分成两部分,一部分比基准元素小,一部分大于等于基准元素。此时基准元素在其排好序后的正确位置,然后再用同样的方法递归地排序划分的两部分。

function quickSort($arr) {
    //先判断是否需要继续进行
    $length = count($arr);
    if($length <= 1) {
     
PHP    2019-09-16 20:23:50    21    0    0

为什么使用 xlswriter

xlswriter 是一个 PHP C 扩展,可用于在 Excel 2007+ XLSX 文件中读取数据,插入多个工作表,写入文本、数字、公式、日期、图表、图片和超链接。

请参考下方对比图;由于内存原因,PHPExcel 与 PHPSpreadSheet 在数据量 相对较大 的情况下无法正常工作,虽然可以通过 修改memory_limit 配置来解决内存问题,但完成工作的时间可能会更长;

它支持以下功能:
一、写入
  • 100%兼容的 Excel XLSX 文件
  • 完整的 Excel 格式
  • 合并单元格
  • 定义工作表名称
  • 过滤器
  • 图表
  • 数据验证和下拉列表
  • 工作表 PNG/JPEG 图像
  • 用于写入大文件的内存优化模式
  • 适用于 Linux,FreeBSD,OpenBSD,OS X,Windows
  • 编译为 32 位和 64 位
  • FreeBSD 许可证
  • 唯一的依赖是 zlib
二、读取
  • 完整读取数据
  • 光标读取数据
  • 按数据类型读取

1.2.8 新特性

1、新增日期写入
$config = [
    'path' => './tests'
];

$fileObject = new \Vtiful\Kernel\Excel($config);
$fileObject = $fileObject->fileName('tutorial.xlsx');

$filePath = $fileObject->header(['date'])
    ->insertDate(1, 0, time(), 'mmm d yyyy hh:mm AM/PM')
    ->output();
2、新增自定义单元格数据类型读取
$config = [
    'path' => './tests',
];

$fileObject = new \Vtiful\Kernel\Excel($config);
$fileObject->openFile('tutorial.xlsx')
    ->openSheet();

var_dump($fileObject->nextRow([
    \Vtiful\Kernel\Excel::TYPE_STRING,
    \Vtiful\Kernel\Excel::TYPE_TIMESTAMP,
]));

基准测试

测试环境:

  • Macbook Pro 13 inch
  • Intel Cor
PHP    2019-08-20 13:52:20    36    0    0

1、一群猴子排成一圈,按1,2,…,n依次编号。然后从第1只开始数,数到第m只,把它踢出圈,从它后面再开始数,再数到第m只,在把它踢出去…,如此不停的进行下去,直到最后只剩下一只猴子为止,那只猴子就叫做大王。要求编程模拟此过程,输入m、n, 输出最后那个大王的编号。

 

function king($n, $m){
    $monkeys = range(1, $n); //创建1到n数组
    $i=0;
    while (count($monkeys)>1) { //循环条件为猴子数量大于1
        if(($i+1)%$m==0) { //$i为数组下标;$i+1为猴子标号
            unset($monkeys[$i]); //余数等于0表示正好第m个,删除,用unset删除保持下标关系
        } else {
            array_push($monkeys,$monkeys[$i]); //如果余数不等于0,则把数组下标为$i的放最后,形成一个圆形结构
            unset($monkeys[$i]);
        }
        $i++;//$i 循环+1,不断把猴子删除,或 push到数组
    }
    return current($monkeys); //猴子数量等于1时输出猴子标号,得出猴王
}
echo king(6,3);
 

2、有一母牛,到4岁可生育,每年一头,所生均是一样的母牛,到15岁绝育,不再能生,20岁死亡,问n年后有多少头牛。

 

 

function niu($y){
    static $num= 1; //定义静态变量;初始化牛的数量为1
    for ($i=1; $i <=$y ; $i++) {
        if($i>=4 && $i<15){ //每年递增来算,4岁开始+1,15岁不能生育
            $num++;
            niu($y-$i); //递归方法计算小牛$num,小牛生长年数为$y-$i
        }else if($i==20){
            $num--; //20岁死亡减一
    }
    return $num;
}
 

3、杨辉三角

 

<?php
/* 默认输出十行,

PHP    2019-08-19 10:40:06    9    0    0

当本地curl需要访问https时,出现SSL certificate: unable to get local issuer certificate错误信息

解决办法:

到http://curl.haxx.se/ca/cacert.pem

下载pem文件,并将文件拷贝到PHP目录在php.ini

增加curl.cainfo = "PHP目录\cacert.pem"

本地下载:cacert.pem

PHP Imagick    2019-07-17 18:03:29    60    0    0

php有一款插件叫做imagemagick,功能很强大,提供了图片的很多操作,图片剪切、压缩、合并、插入文本、背景色透明等。并且有api方法调用和命令行操作两种方式,如果只是简单处理的话建议api方法调用,如果是很复杂的操作建议服务器端搭shell命令行操作,因为api方法调用同操作对比命令行他更吃内存,并且效率没有命令行那么高。

本文章就对于这些常见操作进行介绍说明

首先要提一声的时候每次通过imageMagic处理图片都会new一个对象出来,当图片处理好之后最好是把这个对象给销毁,它会占用cpu和内存,如果你不在乎这些小细节的话就当做我没有说,接下来进入正题。

图片宽高压缩:通过调用api中的 thumbnailImage 方法,可以实现图片宽高设置,这个操作不会影响图片的质量,是同大小压缩。

代码如下


1 $codeLogo = new \Imagick( '图片路径' );2 $codeLogo->thumbnailImage( '图片高','图片宽'); 3 header("Content-Type: image/{$image->getImageFormat()}"); 4 echo codeLogo; 5 exit;

 


图片存储大小压缩:通过调用api中的 setImageCompressionQuality 方法,可以实现图片存储大小设置,但是后带参数越小那么图片清晰度越差,但是图片存储大小会越小那么web加载的时候就越快,压缩率请根据实际情况进行调整。

代码如下

code = new \Imagick( '图片路径' );
$code->setImageCompressionQuality('缩放比例');
header("Content-Type: image/{$image->getImageFormat()}");
echo $image->getImageBlob( );

图片合并: 通过imageMagick可以实现多个图片合并到一张图片中,但是在合并的时候需要根据被覆盖图片的高和宽来确定覆盖图片的xy坐标,获取被覆盖图片的高和宽可以通过方法getImageGeometry来获取图片属性,然后得到高和宽,然后进行定位计算,下边的代码是将覆盖图片水平、垂直居中。

代码如下


 $code = new \Imagick( '被覆盖图片路径');
 $codePro 
PHP Imagick    2019-07-17 11:52:30    28    0    0

前言

给图片添加水印,是一个很常见的需求。但是该需求的实现却不简单。

问题

通常添加文字水印,是gd库的imagefttext方法。但是尝试之后,发现图片变成静态了。不符合需求。

利用搜索引擎,查询无数,发现gd扩展不合适解决这个问题。此时需要使用一个新的扩展
imagick

该扩展除了在gif图片过大的情况,存在速度问题,其他情况下表现良好。

解决

在尝试了很多教程,失败无数次。于是忍痛去阅读英文文档,写出正确的代码。

代码如下:

$im = new Imagick("2.gif");
$draw = new ImagickDraw();
$draw->setFont('LOKICOLA.TTF');
$draw->setFontSize( 50 );
$draw->setFillColor(new ImagickPixel("red"));
$text = "wuwenfu";

foreach ($im as $frame) {
    $frame->annotateImage($draw, 100, 120, 0, $text);
}

//写入到文件
//$im->writeImages("2_small.gif", true);
//输出到浏览器。
header( "Content-Type: image/gif" );
echo $im->getImagesBlob();

原图: 

 水印:

 

1/2