2008年1月27日星期日

PHP get client IP and ip2long function

[php title="得到客户端IP地址"]
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$realip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
$realip = $_SERVER['HTTP_CLIENT_IP'];
} else {
$realip = $_SERVER['REMOTE_ADDR'];
}

$realip = ip2long($realip);
[/php]

ip2long 两个算法:

[php]
function ip2int($ip){
//我们先把ip分为四段,$ip1,$ip2,$ip3,$ip4
list($ip1,$ip2,$ip3,$ip4) = explode('.', $ip);
//然后第一段乘以256的三次方,第二段乘以256的平方,第三段乘以256
return $ip1*pow(256,3)+$ip2*pow(256,2)+$ip3*256+$ip4;
}
[/php]

[php title="用位运算"]
function ip2int($ip){
list($ip1,$ip2,$ip3,$ip4)=explode('.', $ip);
return($ip1>>24)|($ip2>>16)|($ip3>>8)|($ip4);
}
[/php]

有些ip转化成整数后,是负数,这是因为得到的结果是有符号整型,最大值是2147483647.要把它转化为无符号的,可以用sprintf("%u",ip2long($ip); 就能转换为正整数。而且得到的结果用long2ip可以正常转换回原来的ip地址。

ip2long也可以用于检测一个IP地址的有效性
int ip2long (string ip_address )

The function ip2long() generates an IPv4 Internet network address from its Internet standard format (dotted string) representation. If ip_address is invalid then -1 is returned. Note that -1 does not evaluate as FALSE in PHP.

注: As of PHP 5.0.0 ip2long() returns FALSE when ip_address is invalid

T-SQL

FROM: http://www.winmag.com.cn/forum/itemdisplay.asp?boardid=11&id=503269
T-SQL允许你使用不同的方法解决一个问题.有的时候,尽管选择不是那么明显,但是却可以让你得到令人满意的和快乐的惊奇.下边让我们解读Dr. Tom Moreau对同一问题不同的可能性的探索.可能我们可以在那些不同的方法之中发现一些珍贵的东西.

让我们以我们的老朋友Northwind数据库为例,这里我们用到的是[order details]表,这个表是一个定单的明细表,和order表是多对一的关系.也就是一个定单对应多个订购的产品.假设你想得到每个定单订购的总价值, 但是不包括59号产品.Listing 1给了我们第一种解法:
[sql title="Listing 1"]
select
OrderID,sum (Quantity * UnitPrice) value
from
[Order Details] o1
where
ProductID <> 59
group by
OrderID
[/sql]
上边的语句很简单,它排除掉了59号产品的定单明细条目,然后进行分组统计.但是如果我们需要忽略掉订购59号产品的定单呢?也就是说我们要统计没 有包含 59号产品的定单的价值.你想到了WHERE, NOT EXIST(S)关键词了吗?Listing 2给了我们第二种方法:
[sql title="Listing 2"]
select
o1.OrderID,sum (o1.Quantity * o1.UnitPrice) value
from
[Order Details] o1
where not exists
(
select
*
from
[Order Details] o2
where
o2.OrderID = o1.OrderID
and o2.ProductID = 59
)
group by
o1.OrderID
[/sql]
如果你不喜欢用exist的话,你可以转化成使用not in:
[sql title="Listing 3"]
select
o1.OrderID,sum (o1.Quantity * o1.UnitPrice) value
from
[Order Details] o1
where 59 not in
(
select
ProductID
from
[Order Details] o2
where
o2.OrderID = o1.OrderID
)
group by
o1.OrderID
[/sql]
尽管Listing 1不满足我们现在的查询条件.但是从性能发面考虑,Listing 1还是最好的,因为它只用到了一次表的扫描.而后边的两个查询都是用到了相关子查询,如果你查看查询计划就回看到,他们都涉及到了两次表的扫描.如果你曾经在 T-SQL用过交叉表查询的话,你就不会对聚集函数里边的case结构陌生.现在我们就把这个非常有趣的方法应用到我们的问题中来:
[sql title="Listing 4"]
select
OrderID,sum (Quantity * UnitPrice) value
from
[Order Details] o1
group by
OrderID
having
sum (case when ProductID = 59 then 1 else 0 end) = 0
[/sql]

HAVING子句起到了对分组的结果进行过滤的作用.如果没有包含59号产品,就会出现0=0,显然这是满足条件的.如果包含了59号产品的订购,就会出现n=0(n<>0),这样的定单就回被过滤掉.查看执行计划你就回发现是一次表的扫描,非常棒!
再来举一个例子:我们这回用到的表是order表,假设我们要统计只通过一个雇员雇员下定单的顾客.你可以想到用子查询not exist来实现:
[sql title="Listing 5"]
select distinct
o1.CustomerID
from
Orders o1
where not exists
(
select
*
from
Orders o2
where
o2.CustomerID = o1.CustomerID
and o2.EmployeeID <> o1.EmployeeID
)
[/sql]
同样的,这个语句可以通过带有HAVING子句的分组来实现.
[sql title="Listing 6"]
select
CustomerID
from
Orders
group by
CustomerID
having
min (EmployeeID) = max (EmployeeID)
[/sql]
另一种方法:
[sql title="Listing 7"]
select
CustomerID
from
Orders
group by
CustomerID
having
count (distinct EmployeeID) = 1
[/sql]

Listing 6和Listing 7查询消耗都要小于Listing 5.相比Listing 5的两次表扫描,他们只进行一次表的扫描.而Listing 6的损耗还要稍微小于Listing 7.但是,Listing 7的一个显著的特点就是它可以适应到一个顾客对应两个雇员,三个雇员......

SQL高手篇:精妙SQL语句介绍

说明:复制表(只复制结构,源表名:a 新表名:b)
SQL: select * into b from a where 1<>1
  说明:拷贝表(拷贝数据,源表名:a 目标表名:b)
SQL: insert into b(a, b, c) select d,e,f from b;
  说明:显示文章、提交人和最后回复时间
SQL: select a.title,a.username,b.adddate from table a,(select max(adddate) adddate from table where table.title=a.title) b
  说明:外连接查询(表名1:a 表名2:b)
SQL: select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUT JOIN b ON a.a = b.c
  说明:日程安排提前五分钟提醒

  SQL: select * from 日程安排 where datediff('minute',f开始时间,getdate())>5

  说明:两张关联表,删除主表中已经在副表中没有的信息
SQL:

delete from info where not exists ( select * from infobz where info.infid=infobz.infid )
  说明:--
SQL:

SELECT A.NUM, A.NAME, B.UPD_DATE, B.PREV_UPD_DATE FROM TABLE1,(SELECT X.NUM, X.UPD_DATE, Y.UPD_DATE PREV_UPD_DATE FROM (SELECT NUM, UPD_DATE, INBOUND_QTY, STOCK_ONHAND FROM TABLE2 WHERE TO_CHAR(UPD_DATE,'YYYY/MM') = TO_CHAR(SYSDATE, 'YYYY/MM')) X, (SELECT NUM, UPD_DATE, STOCK_ONHAND FROM TABLE2 WHERE TO_CHAR(UPD_DATE,'YYYY/MM') = TO_CHAR(TO_DATE(TO_CHAR(SYSDATE, 'YYYY/MM') ¦¦ '/01','YYYY/MM/DD') - 1, 'YYYY/MM') ) Y, WHERE X.NUM = Y.NUM (+)AND X.INBOUND_QTY + NVL(Y.STOCK_ONHAND,0) <> X.STOCK_ONHAND ) B WHERE A.NUM = B.NUM
  说明:--
SQL:

select * from studentinfo where not exists(select * from student where studentinfo.id=student.id) and 系名称='"&strdepartmentname&"' and 专业名称='"&strprofessionname&"' order by 性别,生源地,高考总成绩
  说明: 从数据库中去一年的各单位电话费统计(电话费定额贺电化肥清单两个表来源)
SQL:

SELECT a.userper, a.tel, a.standfee, TO_CHAR(a.telfeedate, 'yyyy') AS telyear, SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '01', a.factration)) AS JAN, SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '02', a.factration)) AS FRI, SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '03', a.factration)) AS MAR, SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '04', a.factration)) AS APR, SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '05', a.factration)) AS MAY, SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '06', a.factration)) AS JUE,SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '07', a.factration)) AS JUL, SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '08', a.factration)) AS AGU, SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '09', a.factration)) AS SEP, SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '10', a.factration)) AS OCT, SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '11', a.factration)) AS NOV,SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '12', a.factration)) AS DEC FROM (SELECT a.userper, a.tel, a.standfee, b.telfeedate, b.factration FROM TELFEESTAND a, TELFEE b WHERE a.tel = b.telfax) a GROUP BY a.userper, a.tel, a.standfee, TO_CHAR(a.telfeedate, 'yyyy')
  说明:四表联查问题:
SQL: select * from a left inner join b on a.a=b.b right inner join c on a.a=c.c inner join d on a.a=d.d where .....
  说明:得到表中最小的未使用的ID号
SQL:

SELECT (CASE WHEN EXISTS(SELECT * FROM Handle b WHERE b.HandleID = 1) THEN MIN(HandleID) + 1 ELSE 1 END) as HandleID FROM Handle WHERE NOT HandleID IN (SELECT a.HandleID - 1 FROM Handle a)

2008年1月18日星期五

FireFox 插件

就开发上而言,目前还没发现一款可以和FF比拟的浏览器,只是有时它占CPU太多,让人不得不在喜欢的同时不免轻叹一声~ “任何东西都是无法十全十美的吧~”。

FireFox的强大,终归于还是它的插件的强大~


FireBug
这是开发时怎样我也不愿意缺少的插件,调样式,调布局,调JS,调AJXA....总之,它的作用太多..

WebDeveloper
这款插件,也可以看样式,另外,它还可以看提交的表单情况,还有一点,可以根据需要清 Cookie


All-in-one Gesture
鼠标手势~用过遨游的人就知道,按住鼠标右键,画来画去,是有惊喜出现的~

ColorZilla
这款在用于取得某个布局的颜色,十六进制的,RBG 值的都有

GoogleToolbar
Google 出的,肯定不会逊色,只是有点太庞大(也许是我心理作用,总感觉装了这个后,FF占CPU就更恐怖了)~

Easy Drugtogo
与 All-in-one Gesture 搭配使用~

Screenrab
截图~