心之所向

后端开发


  • Home

  • Tags

  • Archives

如何更改mac os的默认php版本

Posted on 2016-04-20

使用mac的童鞋都知道,mac自带有php,apache等,使得php开发环境的搭建异常简单,但是mac自带的php版本普遍老旧,而且许多扩展都没有编译进去,例如mcrypt等。因此在本地调试时,也就导致当我们需要某项php扩展支持时,还需重新编译,非常麻烦(因为要用到许多shell命令,更可怕的是一旦安装时出现其他依赖未安装问题,那真是够你折腾一阵了)。而我们在mac上安装的lamp以及mamp等集成开发环境,大多有众多的php版本可选,且开启关闭扩展都很简单。所以,如果能把mac上的默认php修改为MAMP等扩展环境中的,那么这些问题就so easy了。
下面我们就介绍如何操作。

  1. 首先,打开terminal。
    然后在用户home目录下执行vi .bash_profile,这个文件也有可能没有,如果没有就新建一个(在用户home目录下)。
  2. 在vi中打开或新建好该文件后在文件末尾添加
    1
    export PATH=/Applications/MAMP/bin/php/php5.4.10/bin:$PATH

==注:“=”号之后,“:”号之前的路径就是你要修改成的php的路径==,我这里选取的是MAMP中自带的5.4版本

  1. 保存后就大功告成了,接着我们验证一下,另开terminal,输入which PHP,有没有发现默认php的路径已经修改好了呢。接下来就可已正常使用了,如果还不行,重启电脑就可以了。

我的博客要有的功能

Posted on 2016-04-20

导航栏

  • 首页
  • 关于
  • 作品展示

后台

  • 发布文章
  • 删除文章
  • 修改文章
  • 保存草稿
  • 回复评论

  • 文章附件下载

  • 文章评论
  • 文章访问统计

文章归档

  • 文章根据目录分类
  • 文章根据月份分类
  • 文章根据标签分类
  • 文章转载,平台包括微信,微博,扣扣空间
  • 文章元素包括:标题,文章内荣,简介,出处
  • 个人作品展示
  • 文章内容页,返回页首
  • 友情链接
  • 文章搜索功能
  • 好看的侧边栏,字体,以及字体背景

《CSS权威指南》学习笔记一

Posted on 2016-04-20

css的全拼为cascade style sheet,直译为层叠样式表。CSS通过为具有相同特征的html元素在文档中的一个位置统一定义样式,取代html的原始时代为每个元素单独描述样式,以及将样式描述与元素结构混合的模式。层叠即,当多个css定义项为同一html元素定义了同一种样式时(例如A定义项与B定义项都为某一p元素定义了颜色属性),这些定义项在同一元素上发生层叠,根据特定标准确定的权重,判断究竟将哪个定义项应用于该元素。

css的核心之一就是选择器。选择器总结,元素选->p,样式类选->.class_name,id选->#id,attribute选:=,部分attribute选:~=、*=、|=、^=、$=

  1. 子块级元素的追评margin+border+padding+width必然等于父级块元素的width.
  2. 在css中,水平方向上,width只能是content的宽度,不包括margin,border以及padding。
  3. 对于块级元素的水平宽度属性,只有width以及margin可设置为auto,其他的要么设置成具体值,要么默认为0.
  4. width,padding不能为负值,margin可以,可以用负值的margin做一些神奇的效果
  5. css中有一个标准是允许浏览器设定一个width的最小值,元素的width不能比这个小,而这个最小值具体是多少却是因浏览器而异。
  6. 如果width和margin都设置为具体值,即过分受限,则用户代理将把margin-right重置为auto.

神奇的图片类型input type=image

Posted on 2016-04-20

神奇的图片类型 input type=image

这两天的工作是给一个客户的项目改bug,项目是用laravel框架做的,还挺大,本来以为正在学习lel的我能学到不少东西,然而,图样!拿到代码的我看了一晌就欲哭无泪了,

我擦!这代码怎么能这么乱?!是坨屎么!!!

我擦!这种写法也行?!

我擦!这中英文混合命名法是怎么做到这么切换自如的?!

天哪,这神奇的代码是怎么跑了这么久的啊!?

然而,这一切都不及我发现的原作者的表单写法。到目前为止,所有的表单提交,一个type="submit"的input或button我都没有看到,但是这些表单竟然都神奇的工作的好好的,我们一起来膜拜一下大神的代码:

大牛的前端表单代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<form>
<input style="width:102.4px; height:38.4px;"
name="imageField3"
type="image"
id="imageField3"
src="/p-explorer/img/del.jpg" onClick='return confirm("确认删除吗?" +
"此操作将会产生以下影响:\n"+"1.修改楼盘对接经理\n"+"2.修改成员归属");'>
<input style="width:102.4px; height:38.4px;"
name="clientlist"
type="image"
id="clientlist"
src="/p-explorer/img/khlb.jpg">
<input style="width:102.4px; height:38.4px;"
name="imageField"
type="image"
id="imageField"
src="/p-explorer/img/save.jpg">
</form>

大牛的后台表单处理代码:

1
2
3
4
5
6
7
8
9
10
11
12
if($request->has('imageField3_x'))
{
//...
}
if($request->input('clientlist_x'))
{
//...
}
if($request->input('imageField_x'))
{
//...
}

点击任意一个图片后台都能做出相应的响应,而我们却没有找到明显的提交的入口,是不是很神奇?
其实,&lt;input&gt;标签的type属性有一个image的可取值,当取值为image时,&lt;input&gt;被称作图片按钮,点击这些图片,表单就会立即提交,且提交的数据中除了正常的表单项还有鼠标单击时在该图片上的水平和垂直偏移量,也就是我们看到的后端处理代码中的imageField3_x等表单中本不存在的项。
引自W3School的解释:

如果 type 属性设置为 image,当用户单击图像时,浏览器将以像素为单位,将鼠标相对于图像边界的偏移量发送到服务器,其中包括从图像左边界开始的水平偏移量,以及从图像上边界开始的垂直偏移量。

对于这种用法,其实比较适合一个表单有多种动作,将form的action置空,表单默认提交到自身地址之后,在后端逻辑代码中像上面代码中那样根据图片水平或垂直偏移量是否存在来判断具体要执行什么动作。这虽然不是什么冷门知识,但是我是真的第一次知道,只怪当初没有完全的看一遍标签属性。希望你们不会遇到这样的坑。。。

《CSS权威指南》学习笔记之水平格式化

Posted on 2016-04-20
  1. 水平定位属性分七个部分:margin-left,padding-left,border-left,width,padding-right,border-right,margin-right.这七个部分的和总要等于父元素的内容宽度值。
  2. margin属性可为负值,其他属性都不能是负值.
  3. margin属性以及width属性可设置为auto,padding,padding不能设置为auto,他们要么设置为具体值,要么默认为0.
  4. 块级元素可分为非替换块级元素(最典型的是p元素)和替换块级元素(eg.img元素)两种。
  5. 对于非替换块级元素,width和margin,设置为auto的情况可分为三种:
    1. 只有一个auto
      • width设置为auto的情况,这种情况是最常见的,内容宽度会铺满
      • margin中的一个设置为auto的,该margin自动延伸至铺满
    2. 有两个auto
      • 两个margin的情况,内容会居中
      • 一个width一个margin的情况,width会延伸至铺满,设置为auto的margin其实显示是0
    3. 三个都是auto
      • 这种情况最常见,width会铺满,两个margin都是0
    4. 都没有设置值
      • 这种情况表现同第三种一样
  6. 对于替换块级元素,情况与非替换块级元素唯一不同的就是,当width设置为auto时,内容宽度并不会铺满,而是会等于块级元素的子元素的自身的宽度属性,以img元素为例,width=auto的情况,内容宽度会设置为该图片的默认宽度,只有当width为明确的值时,内容宽度才会发生改变。当然,对于图片元素来说,当width设置为固定值切不等于图片的默认宽度值时,元素的height也会按比例发生变化。
  7. 尽量不要用百分比来设置width,因为没有办法yongwidth来控制全部的属性,例如border的宽度必须用em,px等明确。

php判断一个session是否存在的三种情况

Posted on 2016-04-20

三种情况

  • 未设置
  • 设置了,但是为空
  • 设置了且不为空

判断方式

  • isset + empty
  • empty

关于Laravel中使用orWhere查询会返回已删除条目的问题

Posted on 2016-04-20

在laravel的model中,可以引入并使用Softdeletes,即软删除功能,所谓软删除就是当程序对数据库中的一条记录执行删除操作时,并不是真的将这条记录从数据库中删除掉,而是相应的在这个记录的事先指定的字段中添加标识,表明该字段已被软删除,而程序之后访问数据库所执行的查询都会跳过这些记录,在laravel中,一般我们都定义这一功能所对应的字段为deleted_at。

我们以User类为例,在定义这个model时引入softDelete,代码如下:

1
2
3
4
class User extends Model{
use SoftDeletes;
dates=['deleted_at'];
}

除此之外还要在数据库users表中增加deleted_at字段,并设置为时间戳类型,可为空**,这样就添加了软删除功能,可以进行软删除了。

问题描述

当执行对一个User实例$user执行删除操作时,laravel程序自动对数据库中对应记录的deleted_at字段赋值,标识它已被删除,接下来进行的查询就会自动跳过该字段。

而我们的问题恰恰就出在这里,对于已经添加SoftDelete(即软删除)的Model,如果使用Eloquent ORM进行orWhere查询,有时会出现已经被删除的字段出现在我们的搜索结果中,是不是很惊讶呢?
博主也是一样的,还以为发现了什么bug,最后发现其实这与laravelEloquentORM查询的实现有关,让我们从一个简单地Eloquent 查询开始。

我们首先在数据库中准备好一下两条数据

我是用户表

name mobile deleted_at
Martin 87654321
John 12345678 2015-12-06 16:23:34

我们对User类执行查询如下:

1
$users=User::where('name','liuhuidong')->first();

这种情况下出来的结果是正常的,会返回相应的结果,我们分析一下这个语句。
在这条语句中,为了表示方便,我们暂且称“->”符号为“链”,在链之前查询语句

1
User::where('name','liuhuidong')

被称为查询构造器的条件构建部分,在链之后的部分first()被称为获取器,其实在获取器之前,语句返回的是一个查询构造器的类,为QueryBuilder,在laravel项目中的完整路径是

1
Illuminate\Database\Query\Builder

这个类有一个函数很实用,即toSql(),这个函数可以返回我们用Eloquent ORM构造的查询真正执行的sql语句,

1
echo User::where('name','Martin')->toSql();

结果如下:

1
select * from `users` where `deleted_at` is null and `name` = 'Martin'

然后我们加入orWhere

1
$users=User::where('name','Martin')->orWhere('mobile','12345678')->first();

这时我们发现已经被删除的第二条字段也出现在了查询结果中。Why?别着急,我们对这个查询同样进行sql语句打印,结果如下

1
select * from `users` where `deleted_at` is null and `name` = 'Martin' or `mobile` = '12345678'

分析

看到这个sql语句我们就知道原因出在哪里了,原因就在于QueryBuilder生成的sql语句的过程是先生成一个

1
`table`.'deleted_at'=null

然后后面再添加上其他的语句,如果用的是where筛选,就用and连接,如果用orWhere筛选,就用or连接,由于sql语句中,and的执行优先级大于or,因此上句中

1
`deleted_at` is null and `name` = 'Martin' 和`mobile` = '12345678'

会分别执行,然后再把两者的结果集合。(sql查询的实现过程可能并非如此,但是我们这样理解有利于解释我们的问题),这就导致了这样的结果。
知道了原因,我们就能知道破解问题的办法了,

解决

我们可以把sql语句改成

1
select * from `users` where `deleted_at` is null and (`name` = 'John' or `mobile` = '13817037826')

根据这个我们就可以设计eloquent查询语句了。可以使用eloquent的高级where群组化参数查询

1
2
3
4
User::where(function($query)){
$query->where('name','='.'Martin')
->orwhere('mobile','like','12345678');})
->get();

我们再次打印sql语句:

1
select * from `users` where `deleted_at` is null and (`name` = 'Martin' or `mobile` ='12345678')

可以看到,除了Eoquent查询自带的deleted_at筛选条件之外语句的其他部分已经被括号括了起来,保证了它们的优先执行,这样问题就迎刃而解了。

注:这里用到了php闭包函数的用法,博主也是刚刚了解,有兴趣的朋友可以深入了解一下。具体如何在其中引入参数,是的查询的参数变为动态的,可以参看这篇文章下FiveSay的回答。

结尾

laravel的创始人Taylorotweel并不认为这是个bug,而认为这是基于sql语句查询中or和and`作用优先级不同导致的无法避免的事,但是,发现该问题的开发者依然要求Taylor在文档中添加相关解释,最后,Taylor做出了妥协,博主已经确认过,在最新的laravel5.1的Eloquent ORM 入门一节,已经有了这一问题的note,有兴趣的朋友可以去看看:传送门

放上github上该issue的讨论:点我

123

Martin

27 posts
30 tags
© 2022 Martin
Powered by Hexo
|
Theme — NexT.Pisces v5.1.3