php继承单例类实现各子类的单例

父类不能被实例化,不能给覆盖。子类实现单例不能使用self,而是用static,它们都是在类体内调用类的方式,区别在于self关键字是在编译时决定它所指代的类,它写在了哪个类中,它指代的就是那个类。而static关键字则是在执行的过程中才决定它所指代的类

abstract class father{
 final protected function __construct(){
 $this->init();
 }

final protected function __clone(){}
 protected function init(){}
 //abstract protected function init();

public static function getInstance(){
 if(static::$instance === null){
 static::$instance = new static();
 }
 return static::$instance;
 }
}

子类声明$instance静态属性,它们从属于各个子类,在父类的getIntance方法中,通过static关键字,调用子类并实例化,然后又赋给子类静态属性$instance。这样就可以实现将获取单例的函数封装在父类的目的。修改子类代码如下:

class Son1 extends Father{
 protected static $instance = null;
 ...
}

class Son2 extends father{
 protected static $instance = null;
 ....
}
发表在 服务器 | 标签为 | 留下评论

PHPCMS v9更换编辑器为百度UEditer

使用phpcms v9发现自带的编辑器从fckedotror 到 ckeditor太老了,批量除去链接都无法使用了。决定更换编辑器。

首先去UEditor官网下载所需对应版本:http://ueditor.baidu.com/website/download.html

下载1.4.3.3 PHP  UTF-8版。

1. 将所下载的程序包解压,得到程序包目录,将程序包目录更名为ueditor。

2. 将ueditor包放入PHPCMS_PATH/statics/js/中。(PHPCMS_PATH为phpcms的入口文件所在路径)

3. 修改ueditor/php/config.json,将上传路径/ueditor/php/upload/image/{yyyy}{mm}{dd}/{time}{rand:6} 改为

/phpcms/uploadfile/{yyyy}/{mm}{dd}/{yyyy}{mm}{dd}{rand:6},符合PHPCMS的路径规则。

4. 修改ueditor/ueditor.config.js配置文件,

1) 自定义工具栏内容: ,toorbars : [[ ********** ]]

这个工具栏图标你可以参照官方文档进行修改,去掉不需要的功能:http://fex.baidu.com/ueditor/#start-toolbar

2) 自定义编辑器宽高: ,initialFrameWidth:655   //初始化编辑器宽度,默认1000

,initialFrameHeight:500  //初始化编辑器高度,默认320

5. 修改PC_PATH/libs/classes/form.class.php文件,

将原来的:

if(!defined('EDITOR_INIT')) {
$str = '<script type="text/javascript" src="'.JS_PATH.'ckeditor/ckeditor.js"></script>';
define('EDITOR_INIT', 1);
}

注释掉,改为:

if(!defined('EDITOR_INIT')) {
$str .= '<script type="text/javascript" src="'.JS_PATH.'ueditor/ueditor.config.js"></script>';
$str .= '<script type="text/javascript" src="'.JS_PATH.'ueditor/ueditor.all.js"></script>';
$str .= '<script type="text/javascript" src="'.JS_PATH.'ueditor/ueditor.parse.js"></script>';
$str .= '<link rel="stylesheet" href="'.JS_PATH.'ueditor/themes/default/css/ueditor.css"/>';
define('EDITOR_INIT', 1);}
$str .= "<script type=\"text/javascript\">\r\n";
$str .= "var editor = UE.getEditor('$textareaid');";
$str .= '</script>';

6. 在ueditor/themes/default/css/ueditor.css中,

/*UI工具栏、编辑区域、底部*/
.edui-default .edui-editor {
 border: 1px solid #d4d4d4;
 background-color: white;
 position: relative;
 overflow: visible;
 -webkit-border-radius: 4px;
 -moz-border-radius: 4px;
 border-radius: 4px;
 width:auto !important;//注:增加此行,使编辑器自适应
}

7. 去编辑器下方除子标题显示:注释掉phpcms/libs/classes/form.class.php中 如下代码:

 /*$ext_str = "<div class='editor_bottom'>";
 if(!defined('IMAGES_INIT')) {
 $ext_str .= '<script type="text/javascript" src="'.JS_PATH.'swfupload/swf2ckeditor.js"></script>';
 define('IMAGES_INIT', 1);
 }
 $ext_str .= "<div id='page_title_div'>
 <table cellpadding='0' cellspacing='1' border='0'><tr><td class='title'>".L('subtitle')."<span id='msg_page_title_value'></span></td><td>
 <a class='close' href='javascript:;' onclick='javascript:$(\"#page_title_div\").hide();'><span>×</span></a></td>
 <tr><td colspan='2'><input name='page_title_value' id='page_title_value' class='input-text' value='' size='30'>&nbsp;<input type='button' class='button' value='".L('submit')."' onclick=insert_page_title(\"$textareaid\",1)></td></tr>
 </table></div>";
 $ext_str .= "</div>";*/

8. ueditor\ueditor.all.js

//在这里加上格式化按钮 去除段落开始留下空格的问题
 re = new RegExp("^((\&nbsp\;)+)*","g");
 ci.innerHTML=ci.innerHTML.replace(re, "");
 ci.innerHTML=ci.innerHTML.replace(/(^\s*)/g, "");
 ci.innerHTML=ci.innerHTML.replace(re, "");
 
 if(isLine(ci,true) && ci.tagName != 'SPAN'){
 if(opt.indent){
 ci.style.textIndent = opt.indentValue;
 }
 if(opt.textAlign){
 ci.style.textAlign = opt.textAlign;
 }
 // if(opt.lineHeight)
 // ci.style.lineHeight = opt.lineHeight + 'cm';

}
发表在 服务器 | 标签为 | 留下评论

关闭百度Ueditor编辑器自动抓取保存远程图片

很简单

修改配置文件ueditor.config.js 上的参数

找到注释去掉,修改为false

//抓取远程图片是否开启,默认true
,catchRemoteImageEnable:false
发表在 服务器 | 留下评论

用php写个nginx的日志分析代码

ini_set ('memory_limit', '1024M');
$log = file_get_contents('upstream_mycar.log');//读取nginx日志
$log=explode("\n",$log);                    
$p = '/^(\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3})\s-\s(.*)\s\[(.*)\]\s"(.*)\"\s(\d{3})\s(\d+)\s"(.*)"\s\"(.*)\"(.*)$/u';//正则分析
foreach($log as $k=>$v){
    preg_match($p,$v,$a_match);
    if($a_match[8]='Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.75 Safari/537.36'){//提取特征匹配
        //echo $a_match[1]."\n";
        $host[]=$a_match[1];//提取ip
    }
    //var_dump($a_match);
}
print_r(array_unique($host));
发表在 服务器 | 标签为 , | 留下评论

windows server 2008和IIS 7.5添加多用户FTP

打开iis管理器,点击添加ftp站点:

指定任意ftp根目录的物理路径:

在FTP根目录下必须新建一个名为localuser的目录,将FTP的用户目录放至localuser目录下,否则用户FTP无法连接,这个很重要,物理路径必须在localuser目录之上。

SSL设置为无,主机名设置不设置都可以,设置了记得对应主机头:

权限设置为所有用户读写:

往后点击打开设置用户隔离:

设置为按目录方式:
在系统下创建用户和localuser目录下按用户名创建对应的目录,并赋予用户读写权限。

重启下ftp,然后尝试连接试试看,有问题给我留言^_^。

发表在 服务器 | 标签为 , | 留下评论

php5.6 connect() to unix:/tmp/php-cgi.sock failed (13: Permission denied)

升级5.6.29后在nginx的日志中出现以下错误:

2017/01/20 10:54:14 [crit] 12936#0: *45 connect() to unix:/tmp/php-cgi.sock failed (13: Permission denied) while connecting to upstream, client:

解决方法在配置文件php-fpm.conf中添加:

listen.owner = www
listen.group = www

 

发表在 服务器 | 标签为 | 留下评论

php升级成5.6.29时候页面乱码问题根源浅析

昨天升级了php为5.6.29结果就出现页面乱码,无法指定编码的情况。找了半天发现页面响应头被指定了编码Content-Typetext/html; charset=UTF-8,继续查找在配置文件php.ini中设置了default_charset = “UTF-8″。

得出结论是:不指定default_charset的时候,页面编码由页面自己的meta标签指定。如果注释掉了, 默认还是utf8,可以设置为空default_charset = “”,这样就没默认了。

 

发表在 服务器 | 标签为 | 留下评论

解决mysql5.6 GTID同步出现The incident LOST_EVENTS occured on the master.

今天在mysql5.6生产环境上做测试,结果应该是执行了grant语句给一账户复制库的权限导致所有从库同步出现一样的错误。

执行:mysql> show slave status\G;

显示同步已经断开,报The incident LOST_EVENTS occured on the master. Message: error writing to the binary log错误!!!!

网上搜索结果竟然是5.6才有的bug,5.5不会有这样的问题,这是什么鬼。

使用二进制日志同步可以使用以下方法解决:
1)使用sql_slave_skip_counter跳过事件,但此方法只适用于基于二进制日志原理的复制,不适用于基于GTID原理的复制。
2)使用slave_skip_errors跳过错误。
3)在从库上做change master操作,重新切换master_log_file和master_log_pos。(由于无效的grant语句执行后会创建新的二进制日志,所以可以指定主库show master status的master_log_file和master_log_pos)

GTID方式同步

网上大部分说重做,如果你确认真的丢失了日志文件而无法恢复那只能重做。如果仅仅是这种需要跳过grant导致的问题,或者你基本可以忽略的同步丢失一点点数据,那就不需要重做了,只要重新设置下同步的位置即可。

首先查询以下两个参数。

Retrieved_Gtid_Set项:记录了relay日志从Master获取了binlog日志的位置
Executed_Gtid_Set项:记录本机执行的binlog日志位置(如果是从机,包括Master的binlog日志位置和slave本身的binlog日志位置)

查到Executed_Gtid_Set:6f723299-523b-11e5-a5bf-00163e0007c9:1-88703056′ 错误的地方,这时候需要跳过它。gtid_purged官方文档可以知道该变量中记录的是本机上已经执行过,但是已经被purge binary logs to命令清理的gtid_set。执行的时候需要加1变成88703057

然后在mysql命令行下执行以下语句:

stop slave;
reset master;
reset slave all;
set global gtid_purged = ‘6f723299-523b-11e5-a5bf-00163e0007c9:1-88703057’;
change master to master_host = ‘x.x.x.x’,master_port = 3306,master_user = ‘user’,master_password=’pwd’,master_auto_position = 1;
start slave;

如果在重新同步的过程中还出现错误的话,可以使用 gtid_next来跳过错误,参数从Retrieved_Gtid_Set上获取,如88703058-88716569只要取后面的即可,不然可能出现can’t无法设置的提示。

stop slave;
set gtid_next=”6f723299-523b-11e5-a5bf-00163e0007c9:88716569″;
begin;commit;
set gtid_next=”AUTOMATIC”;
start slave;

show slave status\G;

看看是否正常了。

发表在 服务器 | 标签为 | 留下评论

Mongodb操作符$exists包含或不包含某个字段

$exists语法

{ “field”: { “$exists”: <boolean> } }

说明

当<boolean>的值为true时,则匹配数据库中含有field这个字段的文档,也包括field这个字段为空的文档。如果<boolean>的值为false,那么查询只返回不包括该field该字段的文档。简单的说,$exists 就是判断一个字段是否存在。

MongoDB中的 $exists 和SQL操作符 exists 不是一个等同的概念。对于SQL的 exists ,涉及到了 $in 这个操作符的概念。

实例

查看下面的例子:

db.test.find({a:{$exists:true,$nin:[5,15]}})

上面这个查询输出test数据库中存在a这个字段,而且qty的值不等于5或15的所有文档。

存在Null值时

假设records数据库中存在如下文档:
{ a: 5, b: 5, c: null }
{ a: 3, b: null, c: 8 }
{ a: null, b: 3, c: 9 }
{ a: 1, b: 2, c: 3 }
{ a: 2, c: 5 }
{ a: 3, b: 2 }
{ a: 4 }
{ b: 2, c: 4 }
{ b: 2 }
{ c: 6 }

用 $exists: true 查询

用 $exists 操作符对字段 a 进行查询:
>db.records.find( { a: { $exists: true } } )

上面的查询将输出包含字段 a 或者字段 a 的值为null的文档结果:
{ a: 5, b: 5, c: null }
{ a: 3, b: null, c: 8 }
{ a: null, b: 3, c: 9 }
{ a: 1, b: 2, c: 3 }
{ a: 2, c: 5 }
{ a: 3, b: 2 }
{ a: 4 }

用 $exists: false 查询

用 $exists 操作符对字段 b 进行查询:
db.records.find( { b: { $exists: false } } )

上面的查询将输出不包含字段 b 的文档:
{ a: 2, c: 5 }
{ a: 4 }
{ c: 6 }

发表在 服务器 | 标签为 | 留下评论

安装fastdfs-nginx-module后nginx运行循环卡死

测试fastdfs的时候,在安装完nginx扩展fastdfs-nginx-module模块后,nginx正常重启,可是出现刷新页面进入死循环卡死状态,之后会504错误,经过后来多次寻找答案发现只要观察nginx_error.log就可以发现错误所在,记住不是查看access.log日志。

 

发表在 服务器 | 标签为 | 留下评论