Pjax的正确使用
以前偶然之间接触到pjax这个插件,眼前一亮,被它惊艳到了。 顿时觉得心痒难耐,便着手测试想要加在博客里,几经折腾,页面的跳转总算是改善许多,但是离我所见到的完美却总是差一步:每次跳转页面都会闪一下。 奈何文档太少,或者说我所遇到的问题水平太low,这个问题也就一直伴随着我的博客。 服务器到期后,我就把博客迁到了github,用着还挺满意,还拉了几个同学也来用这个,这两天有个同学换了套别人做的模板,让我又见识到了pjax的魅力。 妈蛋,不能忍。 看文档没能解决我的问题,那我找别人的源码去。 于是今天下班路上,扒了几篇码云的源码,终于是解决了这个伴随已久的不完美! 123456789101112131415161718192021<script type="text/javascript"> layui.config({ base: '/js/' ,version: false }).extend({ index: 'index' ,pjax: 'pjax' }).use(['pjax','index'],function (){ var $ = layui.jquery; $(function () { $(document).pjax('a', '#main',{fragment:'#main'}); $(document).on('pjax:start', function () { NProgress.start(); }); $(document).on('pjax:end', function () { NProgress.done(); }); }); });</script> 因为引入了layui,虽然在这个版本的博客里没什么大用,我还是把pjax裹了一层做成了layui的扩展。 之前我是这么写的: 1$(document).pjax('a', '#main'); 今天在对比之下,发现我少了 {fragment:’#main’},加进去一试,好了。 原来我曾经离完美只差一步之遥。 这个东西应该是指定新页面所替换的位置,也就是在拿到新页面的内容以后会在这个元素里边替换。 应该就是这么个意思吧…… 解决了,挺开心的,就是觉得我真的该再下下功夫学英文了。
CentOS 7.2 64位安装LNMP php7+Mysql 5.7搭建教程
前前后后搭建过无数次环境,大大小小的坑也差不多都踩了,今天趁着腾讯搞活动,120块买了台16个月的服务器,想着晚上把环境搭建下吧,结果把之前的文档掏出来发现是没更新的,最新版在公司…… 算了,老子再搞一遍,放在网上随便看。 更新组件123456789yum -y updateyum -y groupinstall 'Development Tools'yum install gcc-c++ patch readline readline-devel zlib zlib-devel bzip2 autoconf automake libtool bison iconv-devel libyaml-devel libffi-devel openssl-devel make yum -y install readline readline-devel ncurses-devel gdbm-devel glibc-devel tcl-devel openssl-devel curl-devel expat-devel db4-devel byacc sqlite-devel libyaml libyaml-devel libffi libffi-devel libxml2 libxml2-devel libxslt libxslt-devel libicu libicu-devel system-config-firewall-tui sudo wget crontabs logwatch logrotate perl-Time-HiRes git cmake libcom_err-devel.i686 libcom_err-devel.x86_64yum install libxml2 libxml2-devel openssl openssl-devel bzip2 bzip2-devel libcurl libcurl-devel libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel gmp gmp-devel libmcrypt libmcrypt-devel readline readline-devel libxslt libxslt-devel libicu-devel openldap-devel 安装Pcre: 123456wget https://excellmedia.dl.sourceforge.net/project/pcre/pcre2/10.31/pcre2-10.31.tar.gztar -xf pcre2-10.31cd pcre2-10.31./configure make make install 安装Libmcrypt: 123456wget https://nchc.dl.sourceforge.net/project/mcrypt/Libmcrypt/2.5.8/libmcrypt-2.5.8.tar.gztar -xf libmcrypt-2.5.8.tar.gzcd libmcrypt-2.5.8./configuremake make install 安装php嗯……最新版7.2开怼 123wget http://cn2.php.net/get/php-7.2.3.tar.gz/from/this/mirrortar -xf mirrorcd php-7.2.3 该编译了,好长… 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566./configure \--prefix=/usr/local/php \--with-config-file-path=/usr/local/php/etc \--enable-fpm \--with-fpm-user=nginx \--with-fpm-group=nginx \--enable-inline-optimization \--disable-debug \--disable-rpath \--enable-shared \--enable-soap \--with-libxml-dir \--with-xmlrpc \--with-openssl \--with-mcrypt \--with-mhash \--with-pcre-regex \--with-sqlite3 \--with-zlib \--enable-bcmath \--with-iconv \--with-bz2 \--enable-calendar \--with-curl \--with-cdb \--enable-dom \--enable-exif \--enable-fileinfo \--enable-filter \--with-pcre-dir \--enable-ftp \--with-gd \--with-openssl-dir \--with-jpeg-dir \--with-png-dir \--with-zlib-dir \--with-freetype-dir \--enable-gd-native-ttf \--enable-gd-jis-conv \--with-gettext \--with-gmp \--with-mhash \--enable-json \--enable-mbstring \--enable-mbregex \--enable-mbregex-backtrack \--with-libmbfl \--with-onig \--enable-pdo \--with-mysqli=mysqlnd \--with-pdo-mysql=mysqlnd \--with-zlib-dir \--with-pdo-sqlite \--with-readline \--enable-session \--enable-shmop \--enable-simplexml \--enable-sockets \--enable-sysvmsg \--enable-sysvsem \--enable-sysvshm \--enable-wddx \--with-libxml-dir \--with-xsl \--enable-zip \--enable-mysqlnd-compression-support \ 结束后make,make install,时间较长,耐心等待。 好了以后,复制一份ini文件备份,然后把php-fpm添加成service 123456cp php.ini-development /usr/local/php/etc/php.inicp sapi/fpm/init.d.php-fpm /etc/init.d/php-fpmcp /usr/local/php/etc/php-fpm.d/www.conf.default www.confcp /usr/local/php/etc/www.conf.default www.confchmod +x /etc/init.d/php-fpmservice php-fpm start 添加php进环境变量: 123vim /etc/profile PATH=$PATH:/usr/local/php/bin export PATH 使修改生效: 1source /etc/profile 查看路径和php版本: 12echo $PATHphp -v 安装nginx安装nginx yum源 1yum localinstall http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm 然后安装nginx: 1yum install nginx 然后,启动下试试? 1service nginx start 访问http://你的ip/ 如果成功安装会出来nginx默认的欢迎界面 没成功就检查下端口是否可以访问 ,虚拟机可以直接干掉防火墙 安装mysql下载文件: 1wget http://dev.mysql.com/get/mysql57-community-release-el7-8.noarch.rpm 开始安装: 12rpm -ivh mysql57-community-release-el7-8.noarch.rpmyum install mysql-community-server 这个比较快,装好开始运行: 1systemctl start mysqld 加入开机自启: 1systemctl enable mysqld 查看默认密码: 12grep 'temporary password' /var/log/mysqld.log 登陆修改密码: 1234567891011121314151617181920212223242526272829303132[root@VM_34_176_centos ~]# mysql -u root -pEnter password: Welcome to the MySQL monitor. Commands end with ; or \g.Your MySQL connection id is 2Server version: 5.7.21Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.Oracle is a registered trademark of Oracle Corporation and/or itsaffiliates. Other names may be trademarks of their respectiveowners.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.mysql> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('Xx..XXXX');#密码不能太简单Query OK, 0 rows affected, 1 warning (0.00 sec)mysql> show databases;+--------------------+| Database |+--------------------+| information_schema || mysql || performance_schema || sys |+--------------------+4 rows in set (0.00 sec)mysql> exit;Bye 安装swoole12345pecl install swoole#添加到php.inicd /etcvi php.iniextension=swoole.so 注:安装好PHP后复制ini文件是因为编译时指定了 1--with-config-file-path=/usr/local/php/etc \ 如果不复制的话也一样能够运行php,但是就无法装扩展了,踩坑千百遍终有一疏,装完swoole发现无法加载,最后查到时这里的问题。 打完收工,一个不小心又搞到凌晨一点,感觉头上凉凉哒~
hexo多设备支持
测试时未知原因,markdown格式的图片标签无法识别,只能用下边hexo推荐的标签。各种尝试,最后推掉重来,好了。 mmp,可能是中间有什么步骤没做好。 1{% img [class names] /path/to/image [width] [height] [title text [alt text]] %} 多设备什么的把源码丢在.io的分支上就好了。 1234567git init #初始化本地仓库git add . #添加文件git commit -m "Blog Source Hexo"git branch hexo #新建hexo分支git checkout hexo #切换到hexo分支上git remote add origin git@github.com:yourname/yourname.github.io.git #将本地与Github项目对接git push origin hexo #push到Github项目的hexo分支上 别的设备只需要拉下代码,然后切换下分支,再执行下 “npm install” 就可以愉快的玩耍了。 后来测试下把源码放在码云也可以的,为了安全起见,把源码放在码云的私有项目去了。 12345新建私有仓库克隆到本地然后把博客源文件丢进去提交搞定
新年快乐,祝大家狗年旺旺旺
一晚上的火车,再加上3个小时的大巴,总算是在年前赶回了家。 看着周围熟悉的环境,听着亲切万分的乡音,瞬间觉得,这一路的折腾也没什么大不了的。 可能这就是“家”所赋予“年”的特殊力量吧。 忐忐忑忑的本命年,终于在今天画上了句号。 回头想想,又特么一如既往地穷了一年。不过,这些在今天看来,似乎都不太重要了,重要的是老子畏畏缩缩的过了本命年,明天又可以继续开始浪~ 哈哈哈哈哈…… 2017”鸡”将结束,2018”犬”力以赴!! 祝大家新年快乐,狗年好合,哦不,狗年大吉,狗年旺旺旺!
openssl_pkey_get_private 内存泄漏
从前,有一块使用 swoole_process 做多线程处理的程序,这个程序有一个奇怪的问题:每运行一个星期左右都会因为内存爆表而停掉。 因为爆表的时间关系,开发的小伙伴们都认为是这段使用 swoole_process 的程序有问题,几经更新改版,代码已经趋于完美,平稳的运行了几天后,小伙伴们终于都松了一口气,终于解决了这个问题。 然而,伴随着百年难遇的血月,这块程序还是在一个意想不到的时间又爆了一次,小伙伴们终于意识到,问题的根本并不在这里,想要找出并改掉这个问题,是何等艰难!但是他们知道,真相只有一个! 又经过几天的排查,凶手终于浮出水面! 呐,就是这孙子:openssl_pkey_get_private 抽出的测试代码: 123456789while(true){ $key = file_get_contents('mock_A.pem'); echo $m=memory_get_usage(),PHP_EOL; $getkey = openssl_pkey_get_private($key, ''); openssl_pkey_free($getkey); echo $mm = memory_get_usage(),PHP_EOL; echo "Before unset: ",$mm-$m ,PHP_EOL; sleep(3);} 结果: 审判结果:该阉的就赶紧阉了吧 行刑后长相: 12345678910$key = file_get_contents('mock_A.pem');$getkey = openssl_pkey_get_private($key, '');while(true){ echo $m=memory_get_usage(),PHP_EOL; openssl_pkey_free($getkey); echo $mm = memory_get_usage(),PHP_EOL; echo "Before unset: ",$mm-$m ,PHP_EOL; sleep(3);} 前线专家点评:纯属冤案,哪儿特么这么容易泄漏,都是因为自己写的不规范! 注:生成公私钥是需要消耗内存的,每次脚本执行结束后会释放掉,但是常驻内存的脚本没有释放的机会,所以每次循环调用都会造成内存增加,持续增加到一定量后系统也就崩了。所以解决办法是在循环开始之前就把密钥生成好。
laravel5.4疑难杂症
公司项目最近翻新了页面,把 bootstrap 完全改成了 layui 。 按照惯例,上线之前先在测试环境跑几天,结果在搭建测试环境的时候,问题就出来了: laravel 版本是 5.4.63 ,服务器的 php 版本是 5.6 ,执行 composer install 时,提示我需要 php7.1 。 吓得我一阵懵逼,难道是什么时候装错扩展了? 把 composer.json 里没什么用的扩展完全去除后再试,结果还是一样。 反复折腾无果,想起还有 update 可以用,遂改为执行 composer update ,终于开始安装了。 小样,还治不了你了!容老夫抽根烟得瑟一下。 下一秒,一个新的报错又砸我个措手不及: class ‘’ not found ! 虽然不知道这个报错是咋回事,但是潜意识觉得应该是某个 Kernel 文件出错了。 找到一份之前的备份,一通对比,终于有所发现: 出错的代码比之前正常的代码多了个 “,”,丫的,太粗糙了! 去掉,再次执行 update ,果然一路畅通无阻。 但是那个该死的 install 是再也没回来。
Layim模块化右键菜单
一直觉得社区那群“先驱”搞的右键菜单要么太丑,要么风格不统一,很难受。 这两天仔细看了看心姐的源码,把历史消息里的右键菜单揪出来改了一把,感觉很良好。 演示地址已挂,请在本地搭建后测试。 调用方法,先引用上边暴露出来的方法,然后: 1234567891011121314151617181920212223242526layim.on('ready', function (options) { $(".layim-list-friend >li > ul > li").menu({ menu: [{ text: "新增", callback: function () { alert("新增"); } }, { text: "复制", callback: function () { alert("复制"); } }, { text: "粘贴", callback: function () { alert("粘贴"); } }, { text: "删除", callback: function () { alert("删除"); } } ] });}); 代码下载地址:码云Github
Layui使用备忘
一个关于 form 渲染特殊用法的解决方案。 需求 :项目中需要做一个带参导入功能 , 画面效果如下图: 遇到的问题 : 弹窗中 select 不显示 select 显示后 , 选中某项时无法把值传入后台 解决办法 : 在弹窗的 success 中使用 form.render(‘select’) 重新渲染select 在弹窗的 success 中增加 select 切换事件监听 , 然后使用变量 uploader 承接 upload.render , 在监听到 select 切换时 , 使用 uploader.config.data = {‘asset_type’: data.value} 来更新 upload 中的 data 参数 , 最后再给 upload 增加 before 参数 , 来接收不切换 select 时的 data 值 . 代码 :html : 123456789101112131415161718192021222324252627<script id="importTpl" type="text/html"> <form class="layui-form layui-form-pane " method="POST" onsubmit="return false" > <div style="padding: 15px;width:400px;margin:0 auto;"> <div class="layui-form-item" > <label class="layui-form-label">导入文件类型</label> <div class="layui-input-block"> <select name="asset_type" id='asset_type' lay-filter="asset_type"> <option value="1" selected>个人贷款</option> <option value="4">票据</option> </select> </div> </div> <div class="layui-form-item" > <button type="button" class="layui-btn layui-btn-primary" id="import"> <i class="layui-icon"></i> 选择文件 </button> </div> <div class="layui-row" > <button class="layui-btn do-import layui-btn-danger " type="button"> 确定导入 </button> </div> </div> </form></script> javascript : 123456789101112131415161718192021222324252627282930313233$('#asset-import').click(function () { layer.open({ area: ['450px', '250px'], title: '项目导入', type: 1, content: $('#importTpl').html(), success: function (layero, index) { form.render('select'); form.on('select', function (data) { uploader.config.data = {'asset_type': data.value}; }); var uploader = upload.render({ url: '/reg/asset-import' , elem: '#import' , accept: 'file' , auto: false , bindAction: '.do-import' , before: function (obj) { uploader.config.data = {'asset_type': $('#asset_type').val()}; } , done: function (res) { layer.close(index); if (res.code == 0) { layer.msg(res.msg, {icon: 1}); } else { layer.alert(res.msg, {icon: 2}); } } }); } });});
代码备忘录
杂七杂八大乱炖。 计算两个日期的差值12345$datetime1 = new DateTime('2009-10-11'); //new DateTime = date_create , 在某些框架中用 new DateTime 需要加 '\' ;$datetime2 = new DateTime('2009-10-13'); $interval = $datetime1->diff($datetime2); echo $interval->format('%R%a days'); 新建文件夹1234$dir = iconv("UTF-8", "GBK", "C:/www/report/"); //linux下可不转码if (!file_exists($dir)){ mkdir ($dir,0755,true);} Ascii 码转换12345678910111213141516function stringFromColumnIndex($pColumnIndex = 0) { static $_indexCache = array(); if (!isset($_indexCache[$pColumnIndex])) { // Determine column string if ($pColumnIndex < 26) { $_indexCache[$pColumnIndex] = chr(65 + $pColumnIndex); } elseif ($pColumnIndex < 702) { $_indexCache[$pColumnIndex] = chr(64 + ($pColumnIndex / 26)) . chr(65 + $pColumnIndex % 26); } else { $_indexCache[$pColumnIndex] = chr(64 + (($pColumnIndex - 26) / 676)) . chr(65 + ((($pColumnIndex - 26) % 676) / 26)) . chr(65 + $pColumnIndex % 26); } } return $_indexCache[$pColumnIndex];}echo stringFromColumnIndex(37); 计算时间过去了多久 天\时\分\秒123456789101112131415161718192021function secsToStr($secs) { $r = ''; if ($secs >= 86400) { $days = floor($secs / 86400); $secs = $secs % 86400; $r = $days . ' 天'; } if ($secs >= 3600) { $hours = floor($secs / 3600); $secs = $secs % 3600; $r .= $hours . ' 小时'; } if ($secs >= 60) { $minutes = floor($secs / 60); $secs = $secs % 60; $r .= $minutes . ' 分钟'; } $r .= $secs . ' 秒'; return $r;}echo secsToStr(545517.1111111111); win10 配置 pthreads 多线程扩展pthreads 只支持 ts 版本的 php , 即线程安全版 phpstudy 自定义版本时总在报错 , 所以换了 xmapp pthreads 下载地址 : 没错,点我 要对应版本号和位数 位数以 php 的为准 下载解压后 , 把 php_pthreads.dll 和 pthreadVC2.dll 复制到 php\ext 下边 php.ini 最后边新增 : extension=php_pthreads.dll 然后再复制一个 pthreadVC2.dll 到系统目录 系统为 32 位的就复制进 C:\Windows\System32 64 位的就复制进 C:\Windows\SysWOW64 重启 xmapp , 新建一个 test.php 12345678910111213141516class AsyncOperation extends \Thread { public function __construct($arg){ $this->arg = $arg; } public function run(){ if($this->arg){ printf("Hello %s\n", $this->arg); } }}$thread = new AsyncOperation("World");if($thread->start()){ $thread->join();} 通过 url 访问 test 文件 , 出现 Hello World 就成功了 或者查看 phpinfo 里边有没有 pthreads 扩展 Js调用系统桌面通知:12345678if (window.Notification && Notification.permission !== "denied") { Notification.requestPermission(function (status) { var n = new Notification("sir, you got a message", { icon: '/img/logo.png', body: 'you will have a meeting 5 minutes later.' }); });} js声音提醒123audioElementHovertree = document.createElement('audio'); audioElementHovertree.setAttribute('src', 'http://w.qq.com/audio/classic.mp3'); audioElementHovertree.setAttribute('autoplay', 'autoplay'); 数据分配:12345678910111213141516$max_worker_num = 30;$data_num = 74;if ($data_num == 0) { return;}for ($i = 0; $i < $data_num; $i++) { $data[$i] = $i;}$min_worker_num = min($data_num, $max_worker_num);$data_arr = array_chunk($data, ceil($data_num / $min_worker_num), true);$worker_num = ceil($data_num / ceil($data_num / $min_worker_num));
laravel 使用笔记
先从最简单的开始: 安装laravel 的安装需要借助 composer ,百度一下,安装,然后去 GitHub 下载 laravel 切换到项目文件夹 ,在不选中任何文件的前提下按住 shift + 鼠标右键,打开 Powershell 或者 cmd 输入:composer install 将 .env.example 另存为 .env 修改数据库配置信息和邮件系统配置信息 然后在命令行输入:php artisan key:generate 生成密钥 然后配置一个本地域名指向 public 文件夹,然后,就好了。[哈哈] 邮件邮件系统配置示例: 12345678MAIL_DRIVER=smtpMAIL_HOST=smtp.mxhichina.comMAIL_PORT=25//465MAIL_USERNAME=m@m-finderMAIL_PASSWORD=邮箱密码MAIL_FROM_NAME=M-finderMAIL_FROM_ADDRESS=m@m-finderMAIL_ENCRYPTION=null//ssl #如果用465端口的话,需要参数 MAIL_ENCRYPTION=ssl 邮件有 3 种模式(可能更多,暂时只接触到3种):一种用 Mail::send 方法一种用 Mail::raw另外一种则是官方文档中的,新建一个类,然后发送邮件时实例化这个类。3 种方法实现的功能一样。Mail::send 1234Mail::send('admin.email', ['orderPrice' => 'laravel'], function ($message) { $message->to('m@m-finder'); $message->subject('我是自定义标题');}); 这个方法第一个参数为视图文件,视图文件的用法等同于普通视图,第二个参数为视图中所用到的数据Mail::raw 1234567$content = '这是一封来自Laravel的测试邮件.';$toMail = 'm@m-finder'; Mail::raw($content, function ($message) use ($toMail) { $message->subject('[ 测试 ] 测试邮件SendMail - ' . date('Y-m-d H:i:s')); $message->to($toMail);}); 基本等同于Mail::send 第三种方法 12345678910php artisan make:controller MailControllerphp artisan make:mail OrderShipped在 OrderShipped 增加内容return $this->view('admin.email')->with([ 'orderName' => 'test', 'orderPrice' => 1500, ]); 然后在要发送邮件的方法中调用: 1Mail::to('m@m-finder')->send(new OrderShipped()); 开放路由,访问下就可以了。 如果需要自定义邮件标题,可以试一下以下方法(未测试): 在你的类中定义一个subject变量: 1public $subject = '这里是邮件自定义标题'; 或者在你的view后跟一个subject方法: 1view('emails.activate-user')->subject('这里定义邮件标题'); 多视图共享数据在 app\Providers 文件夹下 boot() 方法中写入要共享的数据即可 , 例如 : 123456789101112public function boot() { $links = Link::orderBy('id', 'desc')->get(); $web_info = SysConfig::first(); $menus = Menu::select('id', 'name', 'type', 'seo_title', 'seo_describe', 'link') ->where('pid', '=', 0) ->where('is_show', '=', '2') ->get(); view()->share('links', $links); view()->share('web_info', $web_info); view()->share('menus', $menus);} 这样写完以后,你会发现你的 migrate 挂了,哈哈 ,解决办法是使用闭包,即 composer 方法: 12345678910111213public function boot() { Schema::defaultStringLength(191); //解决数据库版本过低无法执行 migrate view()->composer(['layouts.home', 'layouts.userhome','layouts.admin'], function($view) { $links = Link::orderBy('id', 'desc')->get(); $web_info = SysConfig::first(); $menus = Menu::select('id', 'name', 'type', 'seo_title', 'seo_describe', 'link') ->where('pid', '=', 0) ->where('is_show', '=', '2') ->get(); $view->with(['links' => $links, 'web_info' => $web_info, 'menus' => $menus]); }); } 文件上传config 文件夹下有一个 filesystems.php,里边是默认的上传地址,可以根据自己的需要做修改或者添加 上传的控制器代码: 12345678910111213141516if ($file->isValid()) { if ($file->getClientSize() > 2097152) { return $this->json_response(1, "请上传小于 2 mb 的图片", 0); } $ext = $file->getClientOriginalExtension(); $realPath = $file->getRealPath(); $type = $file->getClientMimeType(); $filename = date('Y-m-d-H-i-s') . '-' . uniqid() . '.' . $ext; $bool = Storage::disk($path)->put($filename, file_get_contents($realPath)); $url = Storage::disk($path)->url($filename); if ($filename) { return ['code' => 0, 'msg' => '', 'src' => $url, 'data'=>['src'=>$url,'title'=>$filename]]; //{"code": 0 ,"msg": "" ,"data": {"src": "图片路径","title": "图片名称"} layui 图片上传接口 }} 访问上传到本地的文件资源,需要先创建一个软连接:php artisan storage:link 一个页面中,如果有 ajax 调取数据的,可以把 ajax 使用的路由和页面的路由名称定义为同一个,不同的是页面是 get ,ajax 是 post 自定义404页面在 app\Exceptions文件夹下的Hander中有个render方法,改造一下: 123456789101112public function render($request, Exception $exception){ if ($exception instanceof ModelNotFoundException) { $exception = new NotFoundHttpException($exception->getMessage(), $exception); } if ( ! config('app.debug')) { return response()->view('errors.500', [], 500); } return parent::render($request, $exception);} 然后在views文件夹新建error文件夹和对应错误代码的blade文件。
