分类 开发 下的文章

字符串替换

REPLACE ( fieldname, search, replace )

数据去重

DELETE ...

DELETE FROM table_copy 
WHERE key IN ( 
    SELECT t.key FROM (
    SELECT key FROM table_copy GROUP BY key having count(*) >1
    ) t
) 
AND id NOT IN(
    SELECT t.id FROM (
    SELECT id FROM table_copy GROUP BY key having count(*) >1
    ) t
)

在CentOS下可以通过shell脚本执行定时任务 在macos下 有类似的功能 使用crontab

crontab的格式:

f1 f2 f3 f4 f5 program
# 分(0-59) 时(0-23) 日(1-31) 月(1-12) 周(0-6) 程序

# 其中如果要执行 每x分钟 则使用 */x
# 如果使用* 表示任意次数

* * * * * curl https://test.com
# 表示每分钟都会使用curl打开 test.com

crontab的基本使用:

sudo -i # 进入root权限
crontab -l # 查看定时任务
crontab -e # 编辑定时任务
crontab -r # 删除定时任务

如何定时执行本地的php项目呢 首先crontab -e打开定时任务

*/10 * * * * /usr/bin/php /Library/WebServer/Documents/...test.php >>/Library/WebServer/Documents/...test.log

*/10 表示 每10分钟执行一次 >> 表示 追加输出到 test.log文件 > 表示覆盖输出到test.log php目录需要使用绝对位置 否则不会以root权限执行,会出现执行时的目录权限问题。

除了命令行php方式运行,还可以用 wget,curl方式打开本地的php脚本

譬如:

* * * * curl http://localhost/...test.php > /Desktop/test.log

说来有点惭愧用了1年多的git至今还没有创建过分支,主要都是把git当成一个线上同步来用。 细想起来是因为我很难集中精力细看git的说明文档,另一方面很多网上的文章说的比较晦涩抽象,很难简明扼要的吸收要点。 但是git这些强大的功能到底作用是什么? 如何和实际工作联系,怎么样简单快速的get到这些功能的意义和使用方式呢? 今天就好好get一下。

git init

“这个文件夹,被我征用了,我要用它来做我的代码版本控制,其他工作就交给git你了。”

初始化仓库 初始化之后,git就会在这里生根发芽。

git clone git@xx.com/sth.git folder

“快帮我建一个和sth一样的仓库,放到folder文件夹就行了。(嗯,仓库我还没建,你看着办)”

克隆仓库到文件夹 如果对这个仓库的历史数据不感兴趣,使用--depth n告诉git,别搞这么沉重,我只关心他现在的样子。 不指定文件夹的话、git会默认使用master自动创建。 git clone --depth 1 git@xx.com/sth.git folder

git pull git@xx.com/sth.git folder

“帮我把sth的最新的代码搬过来,放在我仓库的folder文件夹里就行。(我喜欢的就是我的)”

从仓库拉取数据

git add file1 file2 file3

“这几个文件以后麻烦多照顾啦。”

让仓库追踪文件。 添加追踪之后,每次文件变化都会被git检查。 git add . (自动添加全部未跟踪的文件)

git status

“魔镜魔镜告诉我,我都对这些代码做了什么修改呀?”

显示当前的文件状态。

git commit

“那就让来我告诉你,这些文件的修改都有什么非同凡响的意义。”

标记当前变化的注释 命令行中需要单独输入commit的具体内容,输入完成后保存,如mac使用 shift+; 然后 wq。

git branch branchName

创建一个分支,意思是: “hi git,把现在的代码库做个时空胶囊,名字叫branchName”(记得单机游戏的存档吗?) 创建完分支,我们可以随时回到当时那个状态,当然也可以在那个时空胶囊的基础上继续发展、产生新的历史~~

git checkout branchName

进入某个分支,意思是:“请把我带回到branchName的时候,我要去创造那个时空的代码啦。” 主分支默认叫master 回到主线使用 git checkout master

拉取的时候可以通过 sparse clone 实现对指定文件夹的拉取

这样做通常是为了只下载核心的代码,不希望文件过多过于臃肿。

后来发现另一个更重要的,特别是在一个项目刚开始克隆别人的项目时,使用 --depth 参数来设置拉取深度更有效。

需要注意的是,可能和版本有关 也可能git语法就是这样。 --depth 需要写在 add,clone之后 不能写在语句结尾,否则是无效的。

在无意间漫游网上的文章时,看到一个指出对JavaScript误解的部分提到了这个关于JavaScript私有对象的问题。

Private Members in JavaScript

在该文章中指出,在对象内部使用 var 创建的变量属于私有变量、这个是外部无法访问的。 在这里var的变量我们换一种说法就是局部变量。事实上不能算是真正的私有属性。

我们知道在面向对象编程中,一个类的属性、方法如果能够被其他类访问调用,那么这个是public 公开属性、方法。 但是他有一个隐式条件就是,他也能被类自身其他的方法访问。类的private 私有属性、方法虽然不能被外部属性访问,但是他是需要满足被同一个父类下的其他方法访问的。

而局部变量是方法内部创建的,他只能在当前方法的生命周期内被调用,如果一个JavaScript对象中包含了多个方法,在方法内部var创建的属性和方法,是不能被其他任何方法、包括同一个类的其他子方法调用。


在现代JavaScript的很多案例中,如果希望保持属性的私有性,我们一般可以采用 封装返回的方式生成对象。

var Constructor = function( id, el ){
    var obj = {};
    var id = id;
    obj.getElement = function(){ return el; }
    obj.getId = function(){ return id; }
    return obj;
}

在上述对象构造方法中,我们可以通过getElement(),getId()分别取出对应的元素和id,但是无法直接使用 .id, .el 的方式获取到对应的值、也无法直接修改更新该值。

在多数现代浏览器中我们都可能会遇到图片跨域被阻止的问题,一般来说跨域问题主要出现在前后端分离,云架构的web系统中。 在两年前的时候通过网上的搜索勉强应付了问题,但是每次使用或多或少还会有需要解决的小问题。这次弄清楚了之后发现之前网上大多数也都是一知半解,并没有解决核心问题,所以导致了瞎试,碰运气的方式来处理。

首先html2canvas跨域问题的原因 我们希望将html渲染为canvas 进而渲染为图像,这就需要将html中的资源加载到临时的canvas中,而这个时候,如果资源和当前页面不同源,就会被canvas认为有污染拒绝加载。这是出于浏览器出于安全的角度做的一个设定。

在这个时候,我们需要做的其实比较简单,在所有因为跨域被拒绝的资源从服务端返回一个header

Access-Control-Allow-Origin: https://aaa.bbb.com
Access-Control-Allow-Methods: POST, GET, PUT, DELETE

诸如网上的一些都是,不需要的:

Access-Control-Expose-Headers: 
Access-Control-Allow-Credentials: true

以阿里云OSS跨域做个说明, 在阿里云OSS后台的基础设置中,我们可以添加跨域设置。 来源:http://aaa.bbb.com METHODS: GET,POST (如果只针对于显示图片 GET就可以了) 允许headers,暴露headers都留空即可。 缓存时间留空或者写一个秒为单位的数字即可。

设置完之后,正常的跨域上传、跨域访问图片就已经可以正常工作了。(比如阿里云的JSSDK上传)

但是我们在html2canvas的部分,依旧是会报跨域问题。 这里的原因是,我们没有在访问跨域图片的时候,发送 origin 参数,这个origin参数需要时我们刚才在后台允许的 来源列表中。

我们为图片或其他资源添加origin可以直接写入到元素中,也可以通过js来添加

<img src="......." crossorigin="https://aaa.bbb.com" > <!-- 图片会发送跨域来源 -->
// var img = new Image();  
// var img = document.querySelector('img');
img.src = "......"; // 图片地址
img.crossOrigin = "https://aaa.bbb.com"; // 跨域来源

这时,我们通过浏览器的开发者工具查看网络请求,即可以看到Request中有一项: Origin: https://aaa.bbb.com

此时跨域问题得到精确解决。


# 原代码
if (isset($value['r']) ) { // 对比属性值
    if(isset($array[$key]) && $array[$key]==$value['r']){
        $module  = str_replace('[if['.$value['v'].']if]',str_replace('::'.$key.'='.$value['r'].'::','',$value['v']), $module);
    }else{
        $module  = str_replace('[if['.$value['v'].']if]', '', $module);
    }
}else if(isset($value['i'])){// 是否含有属性
    if(isset($array[$key]) && strstr($value['i'],(string)$array[$key])){
        $module  = str_replace('[if['.$value['v'].']if]',str_replace('::'.$key.'^'.$value['i'].'::','',$value['v']), $module);
    }else{
        $module  = str_replace('[if['.$value['v'].']if]', '', $module);
    }
}else if(isset($value['sub'])){ // 是否含有子属性
    if( isset($array[$value['c'][0]][$value['c'][1]])){
        $module  = str_replace('[if['.$value['v'].']if]',str_replace('::'.$key.'::','',$value['v']), $module);
    }else{
        $module  = str_replace('[if['.$value['v'].']if]', '', $module);
    }
}else{
    if (isset($array[$key])) {
        $module  = str_replace('[if['.$value['v'].']if]',str_replace('::'.$key.'::','',$value['v']), $module);
    }else{
        $module  = str_replace('[if['.$value['v'].']if]', '', $module);
    }
}

# 优化后

$origin = '[if['.$value['v'].']if]';
$condit = isset($value['g']) && isset($value['r'])  ? '::'.$key.$value['g'].$value['r'].'::' : '::'.$key.'::' ;
$replacement = str_replace($condit,'',$value['v']);

if ( 
    !isset($value['g']) && !isset($array[$key]) ||
    # 不存在值且不存在对比

    in_array($value['g'], ['>','<','>=','<=','=']) && !(isset($array[$key]) && MIXER::compareValue($array[$key],$value['g'],$value['r'])) ||
    # 对比属性值

    $value['g']=='^' && !(isset($array[$key]) && strstr($value['i'],(string)$array[$key]) ) ||
    # 是否含有属性

    $value['g']=='.' && !(isset($array[$value['c'][0]][$value['c'][1]])) 
    # 是否含有子属性
) {

    $replacement = '';
}

$module  = str_replace($origin, $replacement, $module);

IF ELSE, ||, && 同属于短路逻辑 在效率上差不多,不需要遍历全部结果,而是有一个优先级的递进式判断。 用||来代替if 逻辑上并没有什么差别。只是在代码简洁上做一些优化。

使用三个变量来描述了一些过程中的临时变量,能够更好的理解这些变量在上下文中的含义,结构上也避免了重复的排布,让代码逻辑更加明确,但是理解成本略微增高,不像原版本中完全是平铺直叙的过程描述。

最近正在做appsite框架传统网站架构的拓展、其中不免有SEO的部分。 在网上做了一点功课,meta中的 description比较关键,keywords据说已经不再受搜索引擎的关照了,不过这种事情现在不能盲目相信,既然做一个网站那么还是应该要照顾好关键词。但是没必要付出过高的人力成本,所以我这里想到的还是使用分词扩展来自动生成关键词。 这样做的好处是,无论搜索引擎是否在意关键词,我们有和内容相关度很高的关键词,这不会对我们带来损失。 基于程序算法生成的关键词,不需要我们花费人力成本,包括可以在后台控制是否开启该功能。

我这里选用的是对php支持比较好的 SCWS分词扩展。 如果分词的目的是更多的语义化分析、情感分析等,那还是应该考虑一下其他的分词库,不过基本上没有php支持。

进入正题

- 阅读剩余部分 -