分类 PHP技术 下的文章

  1. 不要使用 mysql_ 类函数
    终于,你不用再看到建议不要使用 mysql_ 函数的提示了。因为 PHP 7 从核心上完全移除了它们,这意味着请你移步至更好的 mysqli_ 类函数,或者更灵活的 PDO 层。
  2. 不要写无用的代码
    这看上去是个无脑建议,但是随着 PHP7 速度的提升掩盖了一些问题使它显得日趋重要。不要仅仅因切到 PHP7 让网站速度变得快点,你就沾沾自喜了。

想理解速度的重要性和如何做的更好,去看看我们这篇文章 初学者加速优化指南。

作为开发者,应该确保按需加载脚本,可能时再组合,编写高效的数据库查询语句,如果可能的话 使用缓存 等等。

  1. 不要在文件末尾使用 PHP 闭合标签
    如果你随便看看,就会发现大部分 WordPress 核心代码文件结尾都省略了 PHP 闭合标签。事实上,Zend 框架尤为明显地 禁止了闭合标签。它并非 PHP 所必须,在文件结尾处省略它,可确保结尾无额外空白。
  2. 如非必须不要引用传参
    我个人非常不喜欢引用传参。我当然知道在某些场合下它很有用,但是多数场合下,它会使得代码难以理解,难以遵循,难以预测结果。

人们认为引用可以使它们的代码更快,不过正如 可敬的 PHP 程序员 的这篇文章所指出的,事实并非如此。

PHP 内置的 shuffle() 或者 sort() 函数,就是糟糕的引用传参案例。 它修改了原数组而不是返回一个打乱的或者排好序的数组,这是完全违背了我们意愿的。

  1. 不要在循环里使用查询
    在循环中使用数据库查询时最糟糕的。他会给系统带来不必要的压力,并且很有可能,你可以在循环外使用查询而更快的得到相同的结果。当我碰到必须这样用的场景时,我通常会通过分成两个查询来构造一个数组的方式来解决。然后循环数组而无需循环查询。

由于 WordPress 的运行方式,这样做可能会有些例外。 get_post_meta() 将从数据库获取一个元数据,如果您正在循环访问特定文章的元数据,则可以在循环中使用它。这是因为当你第一次使用它的时候,WordPress 实际上取得了所有的元数据并缓存了起来。 之后的调用实际上是调用缓存数据而不是调用数据库。

解决这些问题的最好办法是阅读函数文档并且使用一些类似 查询监听器 的东西。

  1. 不要在 SQL 查询中使用 *

好吧,这更像是一个 MySQL 的问题,但我们更倾向于在代码中编写 SQL 语句,所以我说这是个公平的游戏。不管什么情况下,如果你能避免使用通配符,那就不要使用,尤其是当你的数据库有很多字段的时候。

明确指定你需要的字段,并且只检索这些字段。这有助于节省内存,保护数据,并且能让事情变得更加清晰明白。

在 SQL 方面,尽可能的了解你可用的函数并测试速度。 当计算平均数,求和以及计算相似的数字的时候,使用 SQL 内置函数而不是 PHP 的函数。 如果你不确定一个查询的速度快慢,测试一下它并和其他做法进行比较,选出最好的那一种。

  1. 不要信任用户的输入
    信任用户输入并不明智。对于用户输入,总是需要过滤,杀毒,转义,校验以及使用回退。 用户输入存在三个问题:我们开发者不可能考虑到所有可能性,经常出错,存心的恶意输入。

一个经过深思熟虑的系统可以防止所有的这些问题。 在使用数据库时,确保使用内置的函数,如 filter_var(),来检查合法性,进行转义,和其他能做的事。

WordPress 有一堆函数可以帮到你。可以瞧一瞧这篇文章来了解更多信息 Validating, escaping and sanitising user data 。

  1. 不要自作聪明
    你的目标就是写出能清晰的表达你的意愿的优雅代码。可能你通过缩短变量名,使用多层级三目逻辑运算和其他小聪明让每个页面节约了0.01秒的加载时间,但是和因此种下你和你的团队头疼不已难以维护的恶果相比,得不偿失。

恰当的命名变量,以简洁明了的方式写出代码文档。更好的做法就是,使用标准化的面向对象的代码风格,或多或少的编写文档,而非使用大量的内联代码注释。

  1. 不要重复造轮子
    PHP 已经存在有一段时间了,网站开发存在的时间甚至更久远。 无论你做过啥,前人肯定已经做过。不要害怕依赖别人的支持, Github, Composer , Packagist 都是你的良师益友。

从日志到颜色处理器,从分析器到单元测试框架,从 Mailchimp APIs 到 Twitter Bootstrap,所有的东西只需要按一个按钮(或者敲一个命令)就能用,去使用它们吧!

  1. 不要忽视其他语言
    如果你是个 PHPer,现在的标准做法是至少了解 HTML,CSS,Javascript 和 MySQL。 当你能很好的处理这些语言的时候,就是再去学习一遍 Javascript 的时候。Javascript 不是 jQuery。你应该学习 Javascript 来有效的利用 jQuery。

我也建议学习 PHP 面向对象的一切。它是个救星,能让你的代码在数量级上得到提升。它也能打开类似 C# 和 Java 语言的大门,在你有了这些经验后,它们能让你更容易明白面向对象编程(OOP)。

通过学习包管理,构建脚本,Coffeescript, LESS, SASS, YAML, 模板引擎以及其他有用的工具来扩展知识面。我也由衷的推荐看看其他框架,尤其是 Laravel 。

当你这些都做得够好了的时候,考虑下 Ruby, Ruby on Rails 以及 Android,iPhone,Windows Phone 的 app 开发? 你可能认为这些毫无意义,因为它们不在你的舒适区和工作需求之内,但它们恰恰是重点。 每种语言都有一些有用的教学知识和一些无害的额外知识。所有顶尖的PHP开发人员都了解其他编程语言,这不是偶然的!

说到IP定位,有百度地图,高德地图,腾讯地图,三者都能通过IP定位得到省市,能得到县城只有腾讯地图,经纬度腾讯和百度比较好用,高德是区域经纬,
这三者中有百度地图和高德地图支持天气查询,只有百度地图有图片显示,高德没有地图三种地图都支持js调用和服务器端调用,建议都用https

无限分类是一个很好的分类方法,需要用到三个字段

id pid title 分别是id 父id 分类名称

生成一个无限分类数组,用到了递归,一般开发中分类最多三级,太多也无用处,理论上无限级分类.

function gettree($pid=0,&$result=array(),$spac=0){
    $spac = $spac+2;
    $row = pdo_getall('item',array('pid'=>$pid));
    foreach($row as $v){
        if($v['pid']==0){
            $v['title'] = $v['title'];
        } else{
            $v['title'] = str_repeat('  ',$spac)."|--".$v['title'];
        }


        $result[] = $v;
        gettree($v['id'],$result,$spac);
    }
    return $result;
}

输出分类 传入父类id,默认是从最顶级0开始的,参数2是选中的

function puttree($pid=0,$selected=0){
    $rs = gettree($pid);
    $str='';
    $str .= "<select name='pid'>";
    $str .= '<option value="0">顶级分类</option>';
    foreach($rs as $key=>$val){

        if($val['id'] == $selected){
            $selectedstr = "selected";
        }else{
            $selectedstr = "";
        }
        $str .= "<option $selectedstr value='".$val['id']."'>".$val['title']."</option>";
    }
    $str .= "</select>";
    return $str;
}

根据子类找到上级上上级分类直到顶级为止

function getmenu($cid,&$result=array()){
    //引用数据库连接资源
$row = pdo_get('item',array('id'=>$cid));
    if($row){
        $result[] = $row;
        getmenu($row['pid'],$result);
    }
    //数组顺序倒序
    krsort($result);

    return $result;

}

根据父类查询子类,直到最终子类为止和上面相反

 function get_cid($cid,&$result=array()){
        $row = pdo_getall('item',array('pid'=>$cid));
        if($row){
            foreach($row as $v){
                $result[] = $v;
               get_cid($v['id'],$result);
            }


        }
        return $result;
    }

实际上1,3,4函数比较有用,掌握这几个就掌握了无限分类.

  • 准备工作
阿里云服务器一台,
已安装centos,git,go语言,
nginx端口占用了80,
开通了https占用了443
已备案域名一枚,已解析二级域名 demo.shanliwawa.top

本地客户端win10系统,运行php环境,端口80,服务器Apache+php,注意nginx会出错解析不了.
  • 下载frp
https://github.com/fatedier/frp/releases
国内 http://diannaobos.iok.la:81/frp/
服务器端选择 64位linux  frp_0.20.0_linux_amd64.tar.gz
客户端选windows64位 frp_0.20.0_windows_amd64.zip

服务器端只需要两个文件frps和frps.ini
解压到根目录下 frp文件夹 通过cd进入frp,进入目录执行,注意权限改为777

启动命令 ./frps -c ./frps.ini &
&表示关闭ssh一样运行
ini配置如下,4443是通信端口,客户端也必须相同,8081是服务器端口,因为80被nginx占用了,我们要用服务器端nginx反向代理,代理配置如下


[common]
bind_port = 4443
vhost_http_port = 8081
  • 反向代理配置
map $http_x_forwarded_for $clientRealip {
   "" $remote_addr;
   ~^(?P<firstAddr>[0-9\.]+),?.*$  $firstAddr;
}
server {
       listen 80;
       server_name demo.shanliwawa.top;
       location / {
           proxy_pass http://127.0.0.1:8081;
           proxy_set_header Host $host;
           proxy_set_header X-Real-IP $clientRealip;  # $remote_addr;
           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
       }
}
  • 客户端配置
解压到D盘frp下,通过cd 进入到frp,只需要frpc和frpc.ini,配置如下,9.9.9.9是我的阿里云IP,4443和上边对应,启动命令:

frpc -c frpc.ini
软件不能关闭,关闭就不能访问了

[common]
server_addr = 9.9.9.9
server_port = 4443
 [web]
type = http
local_ip = 127.0.0.1
local_port = 80
custom_domains =demo.shanliwawa.top

现在就能通过demo.shanliwawa.top访问本地服务器了

织梦操作中,难免不遇到数组,在list标签中,就可以使用数组操作.

[field:array runphp='yes']
    if(@me['litpic']=='/images/defaultpic.gif'){
            @me=    get_imgs(@me['id'],1);
    }else{
            @me=@me['litpic'];
}[/field:array]

这里还应用了一个自定义函数get_imgs().功能是获取图片中第一张.判断了是否有缩率图,有就输出,没有就获取第一张图片.

这里还出现了@me,他是一个代表值,既可以是输出@me=,也可以是传入参数值.
[field:global.autoindex/]
在list这种数剧列表中会输出1,2,3自然数,相当于数组的$k=>$v中$k

顺便说一句,遇到不能在模板中操作的,可以用自定义函数解决,一般常用到数据库操作.明天会讲解在织梦中使用ajax.虽然ajax很简单,但是要在织梦中使用,还是需要一番研究才实现的.

从今天开始,逐渐讲解dedecms建站系统的使用,会有一些开发技巧放出.首先来大概介绍一下使用.

  • 大概目录讲解.后台目录dede会自动登录,模板templates,里面default是默认目录,我们可以建自己的目录作为模板.
  • 模板分三部分,分别是index_开始是封面,也可以作为单页使用;list_是列表页面;article_为文章详细页.后面带_m是移动端模板页面,每个模板都要有对应的移动端模板;
  • 关于菜单制作,需要建立栏目
  • 与表单有关的可以使用自定义表单,然后将生成的代码做成模板即可;
  • 织梦忘记密码 表_admin 密码c3949ba59abbe56e057f对应登录密码123456
    以后会逐步讲解更多织梦技巧

在phpstudy2018中,本想部署5.6php+nginx+虚拟域名tp5.com,可是无论如何都不成功,文件程序目录在c:\www\tp5里面,在这样环境中显示500错误,最后还是没有找到问题,部署微擎和dedecms都没有任何问题.网上有很多修改配置文件的,没有一个可以成功的,我把目录指向c:\www\tp5\public,最终放弃.

只好改成apache试试看看能不能成功,没想到成功了一样是指向c:\www\tp5\public,配置文件要在vhosts.ini里面,全部配置如下

<VirtualHost _default_:80>
DocumentRoot "C:\www"
  <Directory "C:\www">
    Options +Indexes +FollowSymLinks +ExecCGI
    AllowOverride All
    Order allow,deny
    Allow from all
    Require all granted
  </Directory>
</VirtualHost>

<VirtualHost *:80>
    DocumentRoot "C:\www\tp5\public"
    ServerName tp5.com
    ServerAlias 
  <Directory "C:\www\tp5\public">
      Options FollowSymLinks ExecCGI
      AllowOverride All
      Order allow,deny
      Allow from all
     Require all granted
  </Directory>
</VirtualHost>

<VirtualHost *:80>
    DocumentRoot "C:\www\hxcms"
    ServerName hxcms.com
    ServerAlias 
  <Directory "C:\www\hxcms">
      Options FollowSymLinks ExecCGI
      AllowOverride All
      Order allow,deny
      Allow from all
     Require all granted
  </Directory>
</VirtualHost>

<VirtualHost *:80>
    DocumentRoot "C:\www\dedecms"
    ServerName dedecms.com
    ServerAlias 
  <Directory "C:\www\dedecms">
      Options FollowSymLinks ExecCGI
      AllowOverride All
      Order allow,deny
      Allow from all
     Require all granted
  </Directory>
</VirtualHost>

<VirtualHost *:80>
    DocumentRoot "C:\wwwweixin"
    ServerName weixin
    ServerAlias 
  <Directory "C:\wwwweixin">
      Options FollowSymLinks ExecCGI
      AllowOverride All
      Order allow,deny
      Allow from all
     Require all granted
  </Directory>
</VirtualHost>

最后访问没有任何问题.
host文件修改如下

127.0.0.1       localhost
127.0.0.1     tp5.com
127.0.0.1       hxcms.com
127.0.0.1       dedecms.com
127.0.0.1       weixin.com

Excel.php

<?php
//没有命名空间类加载方式 调用类用\
require_once IA_ROOT . '/framework/library/phpexcel/PHPExcel.php';
require_once IA_ROOT . '/framework/library/phpexcel/PHPExcel/IOFactory.php';

class Excel{

   
    private $xls='.xls';//保存文件后缀
     private $xlsx='.xlsx';//保存文件后缀
    private $excelPath;//文件保存的绝对位置
    private $letter=["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"];
    //Excel5和Excel2007
    private $ExcelVersion=['Excel2007','Excel5'];

    private $sheetNum=0;
    //phpExcel实例化对象
    private $phpExcel;
    private $phpWriter;
    private $xlsReader;
    private $phpSheet;

    public function __construct()
    {
        //  实例化PHPExcel类
        $this->phpExcel = new PHPExcel();
       
    }

    /**
     * 创建新的Sheet 支持链式操作
     * @param string $sheet_title
     * @param array  $data       导出数据内容
     * @param array  $excelHeader导出表头
     * @return $this
     * @throws \Exception
     * @throws \PHPExcel_Exception
     */
    public function createSheet($sheet_title='Sheet1',$data=[],$excelHeader=[])
    {
        if ( empty($excelHeader)||!is_array($excelHeader)){
            throw new Exception("Parameter is incorrect");
            return $this;
        }
        $sheet_num = $this->getNewSheetNum();
        $objPHPExcel=$this->phpExcel;
        $objPHPExcel->createSheet($sheet_num);
        //设置当前的sheet
        
        $objPHPExcel->setActiveSheetIndex($sheet_num);
        //设置sheet的name
        $objPHPExcel->getActiveSheet()->setTitle($sheet_title);
        $sheet=$objPHPExcel->getActiveSheet();
       //表头设置
        $excelHeader=array_values($excelHeader);
        foreach($excelHeader as $item=>$value){
            $sheet->setCellValue($this->letter[$item]."1",$value);
        }
       //表内容设置
        foreach($data as $item=>$value ){
            $value=array_values($value);
            foreach($value as $i=>$v)
            //$sheet->setCellValue($this->letter[$i].($item+2),$value[$i]);
            $sheet->setCellValueExplicit($this->letter[$i].($item+2),$value[$i], PHPExcel_Cell_DataType::TYPE_STRING);
        }
        return $this;
    }


    /**
     * 导出下载
     * @return output  
     */ 
    public function downFile($excelName='',$ver='xls')
    {
        ob_start();
        if(empty($excelName)){
            $excelName = 'Excel'.date("Ymdhis");
        }
        try{
            if($ver=='xls'){
              $this->phpWriter = PHPExcel_IOFactory::createWriter($this->phpExcel,$this->ExcelVersion[1]);
              $ext = $this->xls;
            }else{
              $this->phpWriter = PHPExcel_IOFactory::createWriter($this->phpExcel,$this->ExcelVersion[0]);
              $ext = $this->xlsx;
            }   
        }catch(Exception $e){
            throw new Exception("Export failed");
        }
        header('Content-Type: application/vnd.ms-excel; charset=utf-8');
        header("Content-Disposition: attachment;filename=".$excelName.$ext);
        header('Cache-Control: max-age=0');
        $this->phpWriter->save('php://output');  
        ob_end_flush();
        die();
    }
    /**
     * 导出保存服务器上
     * @param  String  $path 保存路径
     * @param  boolean $activate 自定义保存路径需要将此处设置为true
     * @return Object  
     */ 
    public function saveFile($excelName='',$filepath='',$ver='xls')
    {
        
        if (empty($filepath)) {
            $filepath  =  IA_ROOT.'/data/Excel/';
        }
        if(empty($excelName)){
            $excelName = 'Excel'.date("Ymdhis");
        }
        if(!$this->checkPath($filepath)){
            throw new Exception("The current directory is not writable");
        } else{
            try{
                 if($ver=='xls'){
              $this->phpWriter = PHPExcel_IOFactory::createWriter($this->phpExcel,$this->ExcelVersion[1]);
              $ext = $this->xls;
            }else{
              $this->phpWriter = PHPExcel_IOFactory::createWriter($this->phpExcel,$this->ExcelVersion[0]);
              $ext = $this->xlsx;
            }  
            }catch(Exception $e){
                throw new Exception("Export failed");
            }
          
            $this->excelPath=$filepath.$excelName.$ext;
            $this->phpWriter->save($this->excelPath); 
            return $this;
        }

    }
    /**
     * 导入基本设置
     * @param  String  $path 保存路径
     * @param  boolean $activate 自定义保存路径需要将此处设置为true
     * @return Object  
     * @throws Exception
     * @throws \PHPExcel_Exception
     */ 
    public function loadExcel($filepath)
    {
      if(!is_file($filepath)){
        throw new Exception("File does not exist");
      }
       try{$type = strtolower( pathinfo($filepath, PATHINFO_EXTENSION) );
            if($type=='xlsx'){
                $xlsReader =  PHPExcel_IOFactory::createReader($this->ExcelVersion[0]);
                $xlsReader->setReadDataOnly(true); 
                $xlsReader->setLoadSheetsOnly(true);
                $this->xlsReader=$xlsReader->load($filepath);
            }elseif('xls'==$type){
                $xlsReader =  PHPExcel_IOFactory::createReader($this->ExcelVersion[1]);
                $xlsReader->setReadDataOnly(true); 
                $xlsReader->setLoadSheetsOnly(true);
                $this->xlsReader=$xlsReader->load($filepath);
            }elseif('csv'==$type){
              $handle = fopen($filepath, 'r');
        $dataArray = array();
        $row = 0;
        while ($data = fgetcsv($handle)) {
            $num = count($data);

            for ($i = 0; $i < $num; $i++) {
                $dataArray[$row][$i] = mb_convert_encoding($data[$i], "utf-8", 'GBK');
            }
            $row++;

        }

        $this->xlsReader= $dataArray;
            }
       }catch(Exception $e){
            throw new Exception("Reading failed");
       }
      return $this->xlsReader;
    }
    /**
     * 获取新的Sheet编号
     * @return int
     */
    protected function getNewSheetNum(){
        $sheet_num=$this->sheetNum;
        $this->sheetNum=$sheet_num+1;
        return $sheet_num;
    }

    /**
     * 检查目录是否可写
     * @param  string   $path    目录
     * @return boolean
     */
    protected function checkPath($path)
    {
        if (is_dir($path)) {
            return true;
        }
        if (mkdir($path, 0755, true)) {
            return true;
        } else {
            return false;
        }
    }
    /**
     * 返回数组的维度
     * @param  Array   $arr 任意数组
     * @return number  数组维度
     */
    protected function array_depth($arr)
    {
        if(!is_array($arr)) return 0;
        $max_depth = 0;
        foreach($arr as $item1)
        {
            $t1 = $this->array_depth($item1);
            if( $t1 > $max_depth) $max_depth = $t1;
        }
        return $max_depth + 1;
    }
}

包含方法有导入,导出,导出模板,支持导入xls,xlsx,csv,导出支持xls,xlsx,使用非常简单

$csv = new Excel();

foreach($rs as $k=>$v){
$data[] = ['用户名'=>$v['username'],'密码'=>$v['password']];
}
$csv = $csv->createSheet('导出表',[],['用户名','密码'])->downFile('文件名','xls');//下载 saveFile('文件名','./','xls')保存到服务器

$csv->loadExcel($_SERVER['DOCUMENT_ROOT'].'/1.xls')->getSheet(0)->toArray();//可读xls,xlsx成数组

$qq = $csv->loadExcel($_SERVER['DOCUMENT_ROOT'].'/1.csv');//读取csv成数组

需要说明 如果导入的数组,数据有空格去除使用下面函数即可

//去除数组中值两端空格
function TrimArray($Input){
    if (!is_array($Input))
        return preg_replace("/(\s|\&nbsp\;| |\xc2\xa0)/","",$Input);

    return array_map('TrimArray', $Input);
}

平常建立网站都希望,www.x.com与x.com是一个网站,如何做到呢?
创建网站时候站点域名一定要带上www.x.com这样去创建网站.
然后我们建立一个.htaccess文件,内容如下,编码utf-8

<IfModule mod_rewrite.c>
RewriteEngine onRewriteCond %{http_host} ^yoby123.cn [NC]
RewriteRule ^(.*)$ https://www.yoby123.cn/$1 [L,R=301]
</IfModule>

里面网站自己改吧
然后把这个文件上传到/www/web/www_yoby123_cn/public_html这样一个目录下就可以,
以后就会自动跳转到带www

我收集制作的 (https://packagist.org/packages/logoove/)

常用函数工具类

composer require logoove/fn dev-master
phpexcel导入导出类

composer require logoove/phpexcel dev-master
pdo操作封装类,类名同微擎1.7版本

composer require logoove/pdo dev-master
oauth2

composer require logoove/oauth2 dev-master
拼音类

composer require logoove/pinyin dev-master
验证码类

composer require logoove/verify dev-master
smarty模板

composer require logoove/smarty dev-master
smtp发送邮件20kb大小类无任何依赖

composer require logoove/smtp dev-master

如果随着php命名空间使用,采用composer会非常方便,不用些重复代码,每个项目只需要通过composer就能重复利用库代码.

1 . 在github上注册一个项目,比如我的,注册为名称fn,项目版权选择的是MIT,然后更新到本地电脑,方便编写库.在本地fn目录下创建src目录,并新建文件Fn.php在src目录下.
2 . 通过cmd命令切换到fn目录下,输入composer init,来创建composer.json文件,注意编码要改成utf-8,生成的好像不是,当然也可以找一个复制过来修改.
composer.json更容是

{
    "name": "logoove/fn",
    "description": "这是一个函数组成的类库,包含大量自定义函数,后续都会从这里更新,以后不用重复定义常见方法",
        "type": "library",
          "license": "MIT",    
    "authors": [{
        "name": "yoby",
        "email": "logove@qq.com"
    }],
  "minimum-stability": "dev",
    "require": {},
    "autoload": {
        "psr-4": {
            "logoove\\fn\\": "src"
        }
    }
}

具体参数意思是name为项目名字,通过/隔开,logoove是我github账号名,fn是项目名字
description是描述,type不用改,authors自己改成你自己的,autoload是自动加载规则,改成你自己路径
完成以后就能够编写Fn.php自己了.
我们可以使用命名空间,命名空间最好统一采用 用户名\项目名
文件名要和你定义的类名相同.
没有使用命名空间的类的加载采用 require_once "PHPExcel.php";这种方式即可
这样我们就可以把以前一些项目改写成符合自动加载类库.

3 . 编写好以后记得提交到到github,然后去 (https://packagist.org) 注册一个帐号,最好也采用github帐号登录.你的每一个库在github上都有独立项目名.最后提交github地址到packagist.org即可.我们以后修改项目在github,那么composer这边如何更新呢,那就是设置同步.
先切换到profile,可以看到底部有个Your API Token,复制下来,然后去github项目的settings->Integrations & services->add server->Packagist,这时候有user,token,domain三个要填写的,我的就是 logoove,刚刚复制的Token,域名就是https://packagist.org/,这样就能自动同步了.
4 . 最后你的库就完成了,任何php项目都能使用了,一个命令搞定,免去每次复制粘贴库代码,你也能分享给更多用户使用

windows安装composer,运行 Composer 需要 PHP 5.3.2+ 以上版本

  • 下载(https://getcomposer.org/Composer-Setup.exe)
  • 安装需要选择php.exe路径,比如phpstudy里面包含很多php,所以可以选择一个合适php版本
  • 安装完成后,需要打开cmd命令,输入composer可以查看安装的信息
  • 更改为国内镜像
    composer config -g repo.packagist composer https://packagist.phpcomposer.com
  • 使用,在cmd下,用cd命令进入到项目目录,执行composer.json文件,命令是
composer install

如果有composer.lock文件需要删除,这样就能执行了

说下我的php是phpstudy,版本php用的5.6nts.

  • 找到phpini文件打开后最后一行去掉分号.phpstudy在C盘下,改成如下,注意你自己安装目录
zend_extension="C:\server\php\PHPTutorial\php\php-5.6.27-nts\ext\php_xdebug.dll"
xdebug.remote_enable = on
xdebug.profiler_enable = off
xdebug.profiler_enable_trigger = off
xdebug.profiler_output_name = cachegrind.out.%t.%p
xdebug.profiler_output_dir ="C:\server\php\tmp"
xdebug.show_local_vars=0
xdebug.remote_handler = dbgp
;设置xdebug的端口为9001
xdebug.remote_port = 9001
;设置idekey
xdebug.idekey="PHPSTORM"
  • 在文件-设置-语言和框架-PHP找到如图,添加php.exe
    图片

请输入图片描述请输入图片描述

请输入图片描述

说到php开发神器phpstorm,下载汉化版https://pan.baidu.com/s/1nHghHl0_D4QFcKZcIA8pTg,可以说非常好用,如果内存4G机器用起来非常卡,怎么来优化呢?

  • 安装过程,很简单,最后把汉化文件复制到安装文件夹的lib目录,打开就是中文版,官方是没有中文版的,安装完成后,网站搜索激活网站就行了.
  • 需要注意设置工作目录尽量文件少,工作目录,否则打开软件索引时候占用全部cpu,卡的不行
  • 还有设置里面关闭不需要的插件,减少内存的大小.
  • 打开滨 目录 PhpStorm64.exe,注意需要安装64位JDK,不要用生成的快捷方式.

经过设置只占用内存不到400MB,不改的话有1G,所以优化还是非常重要的,后面介绍设置phpstorm xdebug断点调试设置.

遇到 占用cpu到100%,很烦,
关闭它有两种方法,一种是关闭启动进程扫描。另一种是关闭windows defende。

  • 鼠标移动到电脑桌面左下角,右键点一下开始,点里面的“运行”,或着win键+R键打开“运行”。
  • 运行里输入:gpedit.msc
  • 依次打开:管理模板----windows组件----windows Defender。
  • 找到windows Defender下的“实时保护”。然后鼠标双击右侧的“不论何时启用实时保护,都会启用进程扫描.
  • 在弹出的设置页面选已禁用。保存就行了。
  • 如果还不能解决我们可以用第二种方法就是禁用windows Defender。
    我们用上面的方法依次打开:管理模板----windows组件--找到-windows Defender,鼠标点一下windows Defender。在右侧找到”关闭windows Defender"并用鼠标双击它
  • 在打开的设置页面,选:已启用。确定之后就会禁用windows Defender。

QQ音乐非常不错,2018年qq音乐修改了网站搜索,以前的接口已经不能用了,笔者在此做了一个新的接口,可以搜索到音乐的真正播放地址,描述,以及相册封面等信息,可以用来做音乐相关应用.接口代码如下,只需要歌曲关键字即可搜索10条数据.

function somusic($keyword="东风破") {//搜索QQ音乐
        $time = time()*1000;
$url = "http://i.y.qq.com/s.music/fcgi-bin/search_for_qq_cp?g_tk=5381&uin=0&format=jsonp&inCharset=utf-8&outCharset=utf-8&notice=0&platform=h5&needNewCode=1&w=".urlencode($keyword)."&zhidaqu=1&catZhida=1&t=0&flag=1&ie=utf-8&sem=1&aggr=0&perpage=20&n=10&p=1&remoteplace=txt.mqq.all&_=".$time."&jsonpCallback=jsonp4";
$ch=curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
$data  =  curl_exec($ch);
curl_close($ch);

$rs=substr($data,7,strlen($data)-8);
$list = json_decode($rs,1);

if(count($list['data']['song']['list'])>0){
$arr = array();
foreach($list['data']['song']['list']  as  $v){
$arr[] = array(
'id'=>$v["songid"],
"songname"=>$v["songname"],
"desc"=>$v["singer"][0]['name']."---".$v["songname"],
'musicurl'=>"http://ws.stream.qqmusic.qq.com/C100".$v['songmid'].".m4a?fromtag=38",
'pic'=>"http://y.gtimg.cn/music/photo_new/T002R150x150M000".$v['albummid'].".jpg?max_age=2592000"
);

}
}else    {
$arr = array();
}


if(count($arr)>0){

$str = $arr;

}else{
$str = "未找到相关音乐";

}
return $str;
    }

请不要做违法应用,支持正版音乐

win10 系统,突然出现github上提交不了了,使用的TortoiseGit2.1版本,出现错误提示"Couldn't agree a key algorithm",网上搜索说是putty版本太低,所以就尝试更新到0.7,依然不行.但是国内的码云是可以的,并不报错.

最后重装也不行,包括重置密钥,最后解决办法,是更新TortoiseGit到2.6版本,问题随即解决,竟然是版本太低了,看来是github网站升级了相关东西.

git还是喜欢图形工具TortoiseGit,虽说命令更高大上,但是图形工具也有自己优势.

php开发终不免要压缩成zip然后弹出下载,当然用php本身提供的也能操作,这里有一个zip.class.php类,操作起来更容易,可以少写很多代码;

下载地址下载
里面的zip目录下
这里还有其他非常多的php常用类

$zip = new Zip();
$zip->setComment(mb_convert_encoding("中文\n",'gb2312','utf-8') . date('Y-m-d H:i'));//压缩文档的说明

$zip->addFile("123内容", "1.txt");//添加文件到压缩文件

$zip->addDirectoryContent("C:/addons/weui","weui/");//前面是要添加文件目录,后面是压缩文件目录,这个是添加目录压缩

$zip->sendZip("1.zip");//弹出压缩

以上介绍的是压缩
解压缩里面也有,可以自行了解