闲者博客 - PHP https://bk1314.com/tag/PHP/ zh-CN Sun, 06 Mar 2022 00:09:15 +0800 Sun, 06 Mar 2022 00:09:15 +0800 PHP循环判断关键词是否存在,如果存在就跳过 https://bk1314.com/59.html https://bk1314.com/59.html Sun, 06 Mar 2022 00:09:15 +0800 飞鱼 1.设置关键词数组,也可以利用mysql调用得到
$keyword_arr=['关键词1','关键词2','关键词3']

2.建立个子程序方便调用

function checKeyword($str='',$keyword_arr=[]){
    foreach ($keyword_arr as $keyword) {
        if (strstr($str, $keyword) != FALSE)return true;
//如果不需要区别大小写可以这么写
//              if (strstr(strtolower($str), strtolower($keyword)) != FALSE)return true;
    }
    return false;
}

3.调用方式演示

 $strtolowerbt="这里为内容查询这段是否有关键词包含";
if(checKeyword($strtolowerbt,$keyword_arr))
{
 continue;   
}
]]>
0 https://bk1314.com/59.html#comments https://bk1314.com/feed/tag/PHP/
php边压缩边下载 https://bk1314.com/58.html https://bk1314.com/58.html Sat, 05 Mar 2022 02:12:00 +0800 飞鱼 php实现边压缩边下载,原理大概就是,每压缩一个文件就输出给浏览器。实现压缩与下载同步进行。

1.关键代码如下

<?php
//根据需求配置内存和执行时间
set_time_limit(360000);
ini_set('memory_limit','20000M');
ob_clean();//洗干净开始干活
header("Content-Disposition: attachment; filename=".date('Y-m-d_hisa').".zip");//设置下载压缩包名称
require ('zip.class.php');//引用类这个类是phpmyadmin/libraries/zip.lib.php  这个的文件 引用记得删除头部的判断
//创建生成器
$zip = new ZipFile();
//开启流式压缩
$zip->setDoWrite();
$data1;
define('BASE_PATH',str_replace('\\','/',realpath(dirname(__FILE__).'/'))."/");//去当前执行文件绝对路径
//define('WWWROOT',$_SERVER['DOCUMENT_ROOT']."/");//网站根目录,如果需要用这个直接屏蔽上面一行代码用这个变量 把下面BASE_PATH替换成WWWROOT即可
$lj=BASE_PATH."bbb";//设置需要打包的目录,方便下面替换避免压缩包把整个路径的文件夹创建
$filearr1 = list_file($lj);//所有待压缩的文件数组,一般只存路径即可
$filearr=toOneArray($filearr1);//多维数组改为一维数组
foreach ($filearr as $key => $value) {
    try{
        //此处可以添加用户连接判断,若是用户取消了下载或断开了链接就终止操作
        $url = $value;
        $file= file_get_contents($url);//获取文件内容,用file_get_content即可,这个是我自己封装的
        $value=str_replace($lj."/", "", $value);//替换路径避免压缩包多余路径文件夹
        $zip->addFile($file,iconv("utf-8","gbk",$value));//调用类的addFile开始压缩
        ob_flush();//输出本次压缩的文件
    }catch(Exception $e){
       log($e);
    }
}
//输出zip文件尾部
$zip->file();
flush();//结束上传,缺少可能会引起压缩文件打不开
function list_file($date){
        //1、首先先读取文件夹
        $temp=scandir($date);
        //遍历文件夹
        foreach($temp as $v){
            $a=$date.'/'.$v;
             if($v=='.' || $v=='..'){//判断是否为系统隐藏的文件.和..  如果是则跳过否则就继续往下走,防止无限循环再这里。
                   continue;
               }
           if(is_dir($a)){//如果是文件夹则执行
           $data1[] = list_file($a);//因为是文件夹所以再次调用自己这个函数,把这个文件夹下的文件遍历出来
           }else{
              $data1[]=["imgpath"=>$a];  //加入到数组里准备返回(特别上面那个他是调用自身那么他也会返回多维数组出来)
           }
        }
       return $data1;
    }
function toOneArray($array)
{
    static $res_arr = [];
    foreach ($array as $v) {
        if (is_array($v)) {
            toOneArray($v);
        } else {
            $res_arr[] = $v;
        }
    }
    return $res_arr;
}
?>

2.引入压缩文件类zip.class.php,是phpMyadmin的压缩方法

<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
 * Zip file creation
 *
 * @package PhpMyAdmin
 */

/**
 * Zip file creation class.
 * Makes zip files.
 *
 * @access  public
 * @package PhpMyAdmin
 * @see     Official ZIP file format: http://www.pkware.com/support/zip-app-note
 */
class ZipFile
{
    /**
     * Whether to echo zip as it's built or return as string from -> file
     *
     * @var  boolean  $doWrite
     */
    var $doWrite      = false;

    /**
     * Array to store compressed data
     *
     * @var  array    $datasec
     */
    var $datasec      = array();

    /**
     * Central directory
     *
     * @var  array    $ctrl_dir
     */
    var $ctrl_dir     = array();

    /**
     * End of central directory record
     *
     * @var  string   $eof_ctrl_dir
     */
    var $eof_ctrl_dir = "\x50\x4b\x05\x06\x00\x00\x00\x00";

    /**
     * Last offset position
     *
     * @var  integer  $old_offset
     */
    var $old_offset   = 0;


    /**
     * Sets member variable this -> doWrite to true
     * - Should be called immediately after class instantiantion
     * - If set to true, then ZIP archive are echo'ed to STDOUT as each
     *   file is added via this -> addfile(), and central directories are
     *   echoed to STDOUT on final call to this -> file().  Also,
     *   this -> file() returns an empty string so it is safe to issue a
     *   "echo $zipfile;" command
     *
     * @access public
     *
     * @return void
     */
    function setDoWrite()
    {
        $this -> doWrite = true;
    } // end of the 'setDoWrite()' method

    /**
     * Converts an Unix timestamp to a four byte DOS date and time format (date
     * in high two bytes, time in low two bytes allowing magnitude comparison).
     *
     * @param integer $unixtime the current Unix timestamp
     *
     * @return integer the current date in a four byte DOS format
     *
     * @access private
     */
    function unix2DosTime($unixtime = 0)
    {
        $timearray = ($unixtime == 0) ? getdate() : getdate($unixtime);

        if ($timearray['year'] < 1980) {
            $timearray['year']    = 1980;
            $timearray['mon']     = 1;
            $timearray['mday']    = 1;
            $timearray['hours']   = 0;
            $timearray['minutes'] = 0;
            $timearray['seconds'] = 0;
        } // end if

        return (($timearray['year'] - 1980) << 25)
            | ($timearray['mon'] << 21)
            | ($timearray['mday'] << 16)
            | ($timearray['hours'] << 11)
            | ($timearray['minutes'] << 5)
            | ($timearray['seconds'] >> 1);
    } // end of the 'unix2DosTime()' method


    /**
     * Adds "file" to archive
     *
     * @param string  $data file contents
     * @param string  $name name of the file in the archive (may contains the path)
     * @param integer $time the current timestamp
     *
     * @access public
     *
     * @return void
     */
    function addFile($data, $name, $time = 0)
    {
        $name     = str_replace('\\', '/', $name);

        $dtime    = substr("00000000" . dechex($this->unix2DosTime($time)), -8);
        $hexdtime = '\x' . $dtime[6] . $dtime[7]
                  . '\x' . $dtime[4] . $dtime[5]
                  . '\x' . $dtime[2] . $dtime[3]
                  . '\x' . $dtime[0] . $dtime[1];
        eval('$hexdtime = "' . $hexdtime . '";');

        $fr   = "\x50\x4b\x03\x04";
        $fr   .= "\x14\x00";            // ver needed to extract
        $fr   .= "\x00\x00";            // gen purpose bit flag
        $fr   .= "\x08\x00";            // compression method
        $fr   .= $hexdtime;             // last mod time and date

        // "local file header" segment
        $unc_len = strlen($data);
        $crc     = crc32($data);
        $zdata   = gzcompress($data);
        $zdata   = substr(substr($zdata, 0, strlen($zdata) - 4), 2); // fix crc bug
        $c_len   = strlen($zdata);
        $fr      .= pack('V', $crc);             // crc32
        $fr      .= pack('V', $c_len);           // compressed filesize
        $fr      .= pack('V', $unc_len);         // uncompressed filesize
        $fr      .= pack('v', strlen($name));    // length of filename
        $fr      .= pack('v', 0);                // extra field length
        $fr      .= $name;

        // "file data" segment
        $fr .= $zdata;

        // echo this entry on the fly, ...
        if ( $this -> doWrite) {
            echo $fr;
        } else {                     // ... OR add this entry to array
            $this -> datasec[] = $fr;
        }

        // now add to central directory record
        $cdrec = "\x50\x4b\x01\x02";
        $cdrec .= "\x00\x00";                // version made by
        $cdrec .= "\x14\x00";                // version needed to extract
        $cdrec .= "\x00\x00";                // gen purpose bit flag
        $cdrec .= "\x08\x00";                // compression method
        $cdrec .= $hexdtime;                 // last mod time & date
        $cdrec .= pack('V', $crc);           // crc32
        $cdrec .= pack('V', $c_len);         // compressed filesize
        $cdrec .= pack('V', $unc_len);       // uncompressed filesize
        $cdrec .= pack('v', strlen($name)); // length of filename
        $cdrec .= pack('v', 0);             // extra field length
        $cdrec .= pack('v', 0);             // file comment length
        $cdrec .= pack('v', 0);             // disk number start
        $cdrec .= pack('v', 0);             // internal file attributes
        $cdrec .= pack('V', 32);            // external file attributes
                                            // - 'archive' bit set

        $cdrec .= pack('V', $this -> old_offset); // relative offset of local header
        $this -> old_offset += strlen($fr);

        $cdrec .= $name;

        // optional extra field, file comment goes here
        // save to central directory
        $this -> ctrl_dir[] = $cdrec;
    } // end of the 'addFile()' method


    /**
     * Echo central dir if ->doWrite==true, else build string to return
     *
     * @return string  if ->doWrite {empty string} else the ZIP file contents
     *
     * @access public
     */
    function file()
    {
        $ctrldir = implode('', $this -> ctrl_dir);
        $header = $ctrldir .
            $this -> eof_ctrl_dir .
            pack('v', sizeof($this -> ctrl_dir)) . //total #of entries "on this disk"
            pack('v', sizeof($this -> ctrl_dir)) . //total #of entries overall
            pack('V', strlen($ctrldir)) .          //size of central dir
            pack('V', $this -> old_offset) .       //offset to start of central dir
            "\x00\x00";                            //.zip file comment length

        if ( $this -> doWrite ) { // Send central directory & end ctrl dir to STDOUT
            echo $header;
            return "";            // Return empty string
        } else {                  // Return entire ZIP archive as string
            $data = implode('', $this -> datasec);
            return $data . $header;
        }
    } // end of the 'file()' method

} // end of the 'ZipFile' class
?>
]]>
0 https://bk1314.com/58.html#comments https://bk1314.com/feed/tag/PHP/
由于POST请求过大导致PHP7无法正常处理解决办法 https://bk1314.com/55.html https://bk1314.com/55.html Thu, 03 Mar 2022 15:40:00 +0800 飞鱼 概述

在巡检优化过程中,发现POST请求至PHP接口处理时,php服务无法读取到请求内容。
通过php.ini开启display_errors = Off后发现页面输出如下内容:

<br />
<b>Notice</b>: file_get_contents(): file created in the system's temporary directory in
<b>/var/www/html/api.php</b> on line <b>10</b><br />
<br />
<b>Warning</b>: file_get_contents(): Unable to create temporary file, Check permissions in temporary files directory. in
<b>/var/www/html/api.php</b> on line <b>10</b><br />

解决办法

由于sys_temp_dirupload_tmp_dir设置的临时目录不存在,mkdir后修改目录权限即可。

[scode type="share"]来源于:闲云博客[/scode]

]]>
0 https://bk1314.com/55.html#comments https://bk1314.com/feed/tag/PHP/
shell脚本每天自动备份mysql数据库命令mysqldump https://bk1314.com/50.html https://bk1314.com/50.html Mon, 28 Feb 2022 18:53:37 +0800 飞鱼 一、mysql提供了一个mysqldump的工具可以方便的导出导入数据库信息

二、使用命令行shell测试执行mysqldump,理解必备的参数,查看生成的sql备份文件是否符合需求

/usr/bin/mysqldump --opt -ubatsing -pbatsingpw -hlocalhost timepusher > /mnt/mysqlBackup/db_`date +%F`.sql

注解:
1、执行 /usr/bin/mysqldump
2、--opt是quick,add-drop-table,add-locks,extended-insert,lock-tables几个参数的合称,一般都要使用,具体意思自行搜索
3、-u数据库用户名 -p数据库用户密码 -h数据库地址 数据库名 > 导出的文件路径
4、date +%F是shell中生成当前日期,格式如2015-11-05,所以成功导出时生成的文件名为 db_2015-11-05.sql
5、下载生成的 sql文件 ,用文本编辑器打开检查,本地导入测试数据库,看是否有问题

三、整理编写比较灵活的shell脚本,方便重用

#!/bin/sh

# Database info
DB_USER="batsing"
DB_PASS="batsingpw"
DB_HOST="localhost"
DB_NAME="timepusher"

# Others vars
BIN_DIR="/usr/bin"            #the mysql bin path
BCK_DIR="/mnt/mysqlBackup"    #the backup file directory
DATE=`date +%F`

# TODO
# /usr/bin/mysqldump --opt -ubatsing -pbatsingpw -hlocalhost timepusher > /mnt/mysqlBackup/db_`date +%F`.sql
$BIN_DIR/mysqldump --opt -u$DB_USER -p$DB_PASS -h$DB_HOST $DB_NAME > $BCK_DIR/db_$DATE.sql

#还原数据库
#用mysql-front导入前一天的 *.sql 文件即可恢复数据

保存到文件或上传到 /usr/local/apache/htdocs/timepusher/sqlBak/sqlAutoBak.sh

四、测试Shell脚本

1、进入到该脚本文件目录 chmod +x sqlAutoBak.sh 添加执行权限,否则会报错 Permission denied
2、./sqlAutoBak.sh ,如果是在windows编写上传的文件可能会报错

/bin/sh^M: bad interpreter: No such file or directory

这是不同系统编码格式引起的:在 windows系统中编辑的 .sh文件可能有不可见字符,所以在 Linux系统下执行会报以上异常信息。可以在Windows上使用Notepad++转换成Unix格式(菜单中选择:编辑>档案格式转换>转换成UNIX)
3、修改后上传继续执行 ./sqlAutoBak.sh ,没有报错。再查看导出的sql文件。

五、压缩mysql的备份数据

1、查看导出来的sql文件,发现其文件大小非常大,mysqldump也提供了生成gzip压缩文件的参数设置
2、sqlAutoBak.sh修改为如下

#!/bin/sh

# Database info
DB_USER="batsing"
DB_PASS="batsingpw"
DB_HOST="localhost"
DB_NAME="timepusher"

# Others vars
BIN_DIR="/usr/bin"            #the mysql bin path
BCK_DIR="/mnt/mysqlBackup"    #the backup file directory
DATE=`date +%F`

# TODO
# /usr/bin/mysqldump --opt -ubatsing -pbatsingpw -hlocalhost timepusher > /mnt/mysqlBackup/db_`date +%F`.sql
# $BIN_DIR/mysqldump --opt -u$DB_USER -p$DB_PASS -h$DB_HOST $DB_NAME > $BCK_DIR/db_$DATE.sql
$BIN_DIR/mysqldump --opt -u$DB_USER -p$DB_PASS -h$DB_HOST $DB_NAME | gzip > $BCK_DIR/db_$DATE.sql.zip

# 还原数据库
# 把 *.sql.zip 使用gunzip 或 本地的解压软件 解压为 *.sql 文件
# 用mysql-front导入前一天的 *.sql 文件即可恢复数据

3、修改后上传继续执行 ./sqlAutoBak.sh ,没有报错。如果用文本编辑器查看导出的 *.sql.gz文件,应该是一堆乱码。
4、下载到本地使用解压软件打开,解压就能看到里面真正的 *.sql 文件了。

六、设置linux定时任务执行该脚本

1、编辑定时任务列表

crontab -e

2、插入下面这一行,因为通常来说5点钟网站的访问量最低

00 05 *   * * /bin/sh /usr/local/apache/htdocs/timepusher/sqlBak/sqlAutoBak.sh
#每天早上 5:00am 执行

3、查看任务是否创建成功

crontab -l

七、第二天检查自动生成的sql文件是否符合要求

如果生成的文件和解压出来查看没有问题,那么这个自动定时备份数据库的脚本就算是完成了。因为生成的文件多了会占用一定的空间,所以建议要定期(比如一个月)清理一下文件。

$、补充

1、如果该数据库的用户没有分配 锁表 的权限,则备份会报错 when using LOCK TABLES 。那是因为mysqldump命令默认在导出时是要锁定表的,所以解决方式有两个。一个是给该用户开放 锁表 的权限;另一个是在命令中加上 --skip-lock-tables 这个参数。即是:

$BIN_DIR/mysqldump --opt -u$DB_USER -p$DB_PASS -h$DB_HOST $DB_NAME --skip-lock-tables | gzip > $BCK_DIR/db_$DATE.sql.gz

]]>
0 https://bk1314.com/50.html#comments https://bk1314.com/feed/tag/PHP/
PHP循环遇到关键词就跳过分享 https://bk1314.com/46.html https://bk1314.com/46.html Sat, 26 Feb 2022 17:36:47 +0800 飞鱼 $keyword_arr=['词1','词2','词3']; //也可以上面数据库存入 function checKeyword($str='',$keyword_arr=[]){ foreach ($keyword_arr as $keyword) { //var_dump($keyword); if (strstr($str, $keyword) != FALSE)return true; } return false; } while($r = mysql_fetch_array($query)){ $bt=$r['ybt'];//标题 $strtolowerbt=strtolower($bt); if(checKeyword($strtolowerbt,$keyword_arr)) { continue; } } ]]> 0 https://bk1314.com/46.html#comments https://bk1314.com/feed/tag/PHP/ php 冷门api goto https://bk1314.com/45.html https://bk1314.com/45.html Sat, 26 Feb 2022 10:14:07 +0800 飞鱼 <?php echo "start"; echo "<hr/>"; goto TEST; echo "<hr/>"; TEST: echo "end"; //goto 不能跳入循环 switch。。。case 函数和类都不可以 //但是可以跳出循环 ]]> 0 https://bk1314.com/45.html#comments https://bk1314.com/feed/tag/PHP/ php 判断是否是https或者http 直接获取域名 https://bk1314.com/44.html https://bk1314.com/44.html Sat, 26 Feb 2022 10:11:19 +0800 飞鱼 //主动判断是否HTTPS function isHTTPS() { if (defined('HTTPS') && HTTPS) return true; if (!isset($_SERVER)) return FALSE; if (!isset($_SERVER['HTTPS'])) return FALSE; if ($_SERVER['HTTPS'] === 1) { //Apache return TRUE; } elseif ($_SERVER['HTTPS'] === 'on') { //IIS return TRUE; } elseif ($_SERVER['SERVER_PORT'] == 443) { //其他 return TRUE; } return FALSE; }
$codepay_config['host'] = (isHTTPS() ? 'https://' : 'http://') . $_SERVER['HTTP_HOST']; //获取域名
]]>
0 https://bk1314.com/44.html#comments https://bk1314.com/feed/tag/PHP/
PHP压缩和解压代码段 https://bk1314.com/43.html https://bk1314.com/43.html Fri, 25 Feb 2022 18:59:25 +0800 飞鱼 [scode type="green"]PHP文件 Zip 压缩[/scode]

<?php
/* creates a compressed zip file */
function create_zip($files = array(),$destination = '',$overwrite = false) {
 
    //if the zip file already exists and overwrite is false, return false
    if (file_exists($destination) && !$overwrite) {
        return false;
    }
 
    //vars
    $valid_files = array();
    //if files were passed in...
    if (is_array($files)) {
 
        //cycle through each file
        foreach ($files as $file) {
            //make sure the file exists
            if (file_exists($file)) {
                $valid_files[] = $file;
            }
        }
    }
 
    //if we have good files...
    if (count($valid_files)) {
        //create the archive
        $zip = new ZipArchive();
        if ($zip->open($destination,$overwrite ? ZIPARCHIVE::OVERWRITE : ZIPARCHIVE::CREATE) !== true) {
            return false;
        }
        //add the files
        foreach ($valid_files as $file) {
            $zip->addFile($file,$file);
        }
        //debug
        //echo 'The zip archive contains ',$zip->numFiles,' files with a status of ',$zip->status;
 
        //close the zip -- done!
        $zip->close();
 
        //check to make sure the file exists
        return file_exists($destination);
    } else {
        return false;
    }
}
 
/***** Example Usage ***/
$files = array('file1.jpg', 'file2.jpg', 'file3.gif');
create_zip($files, 'myzipfile.zip', true);
?>

[scode type="green"]PHP解压缩 Zip文件[/scode]

<?php
/**
 * @param $file - path to zip file
 * @parm $destination - destination directory for unzipped files
 */
function unzip_file($file, $destination) {
    // create object
    $zip = new ZipArchive() ;
    // open archive
    if ($zip->open($file) !== TRUE) {
        die ('Could not open archive');
    }
    // extract contents to destination directory
    $zip->extractTo($destination);
    // close archive
    $zip->close();
    echo 'Archive extracted to directory';
}
?>
]]>
0 https://bk1314.com/43.html#comments https://bk1314.com/feed/tag/PHP/
PHP寻找两个字符串的相似性 https://bk1314.com/42.html https://bk1314.com/42.html Fri, 25 Feb 2022 18:57:11 +0800 飞鱼 [scode type="blue"]PHP 提供了一个极少使用的 similar_text 函数,但此函数非常有用,用于比较两个字符串并返回相似程度的百分比。[/scode]

<?php
    similar_text($string1, $string2, $percent);
    //$percent will have the percentage of similarity
?>
]]>
0 https://bk1314.com/42.html#comments https://bk1314.com/feed/tag/PHP/
PHP强制性文件下载 https://bk1314.com/41.html https://bk1314.com/41.html Fri, 25 Feb 2022 18:54:59 +0800 飞鱼 <?php /** *@param $file - path to file */ function force_download($file) { if ((isset($file)) && (file_exists($file))) { header("Content-length: " . filesize($file)); header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="' . $file . '"'); readfile("$file"); } else { echo "No file selected"; } } ?> ]]> 0 https://bk1314.com/41.html#comments https://bk1314.com/feed/tag/PHP/