Archive for the ‘技术’ Category

识别用户是否是通过手机访问

Thursday, October 9th, 2008

今天花了些时间研究这个问题, 不过目前为止没有找到比较完美的解决方案, 简单说说吧.

现在网上一般有这样几种方法:

第一种是根据浏览器发送的HTTP_USER_AGENT来判断用户是否是通过手机访问网站. 这种方法比较普遍, 可以通过匹配关键字适应大多数手机, 但由于HTTP_USER_AGENT格式并没有标准规范并且不是HTTP协议必须的参数, 所以无法适应所有手机或者所有浏览器, 有些手机甚至不发送HTTP_USER_AGENT.

注: 可以在网上搜到别人搜集的各型号手机和浏览器的HTTP_USER_AGENT

第二种方法是根绝浏览器发送的HTTP_ACCEPT, HTTP_ACCEPT可以判断浏览器支持哪些格式的页面, 比如WAP, HTML, XHTML, XML等, 但对于判断用户是否通过手机访问并不是非常准确, 因为HTTP_ACCEPT不是同样必须的, 多数浏览器并不会在HTTP_ACCEPT中进行过多的描述, 比如一个浏览器如果声明了自己支持wml那它可能支持wml, 但是如果不声明wml并不代表就一定不支持wml.

比如Firefox3的HTTP_ACCEPT是这样的:

text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8 

而黑莓8800的HTTP_ACCEPT是这样的

application/vnd.rim.html, text/html, application/vnd.wap.xhtml+xml, text/vnd.sun.j2me.app-descriptor, image/vnd.rim.png,image/jpeg, application/x-vnd.rim.pme.b, application/vnd.rim.ucs, image$1.gif;anim=1, application/vnd.rim.jscriptc;v=0-8-8, application/x-javascript, application/vnd.rim.css;v=1, text/css;media=handheld, application/vnd.wap.wmlc;q=0.9, application/vnd.wap.wmlscriptc;q=0.7, text/vnd.wap.wml;q=0.7, */*;q=0.5 

还有一种方法有人说可以判断用户的IP, 原理也简单, 因为在国内GPRS上网是通过代理连接的, 所以用户的IP可能是固定的几个, 但是我并不确定手机不能够通过其他方式上网, 比如3G, 或者说我用手机模拟器登录的时候就有可能出错, 或者说如果我用手机当猫那么会将我通过电脑进行的访问当作手机来处理.

还有一种方法我觉得很不错, 如果浏览器支持javascript的话, 可以判断显示器的尺寸, 没有人会用一个19寸大的手机吧?

说来说去, 还是没有找到完美的解决方法, 不过综合这几种方法写了一个函数.

/**
 * 是否是通过手机访问
 *
 * @return bool 是否是移动设备
 */
function isMobile()
{
    // 如果有HTTP_X_WAP_PROFILE则一定是移动设备
    if (isset($_SERVER['HTTP_X_WAP_PROFILE'])) {
        return true;
    }

    $keywords = array('nokia', 'sony', 'ericsson', 'mot',
        'samsung', 'sgh' ,'lg', 'sie-',
        'philips', 'panasonic', 'alcatel', 'lenovo',
        'cldc', 'midp', 'wap', 'mobile');
    // 从HTTP_USER_AGENT中查找手机浏览器的关键字
    if (preg_match("/(" . implode('|', $keywords) . ")/i",
        strtolower($_SERVER['HTTP_USER_AGENT']))) {
        return true;
    }

    if (isset($_SERVER['HTTP_ACCEPT'])) {
        // 如果只支持wml并且不支持html那一定是移动设备
        // 如果支持wml和html但是wml在html之前则是移动设备
        if ((strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') !== false)
        && (strpos($_SERVER['HTTP_ACCEPT'], 'text/html') === false
        || (strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml')
        < strpos($_SERVER['HTTP_ACCEPT'], 'text/html')))) {
            return true;
        }
    }

    return false;
}

面向对象的访问控制

Monday, May 5th, 2008

这两天有在看php5的面向对象的一些教程, 因为php4用的比较多,所以对面向对象这个概念并不是很熟悉.

这里只是简单记录一下关于public, private和protected.

public(公共的)应该比较容易理解, 完全公开, 任何地方都可以访问, 包括该类内部, 外部, 子类等等.

<?
class a{
	public $a;

	function __construct(){
		$this->a = "1";
	}

	function test(){
		echo $this->a;
	}
}

class b extends a{
	function test2(){
		echo $this->a;
	}
}

$a = new a;
$a->test();
// 这里说明public属性对象内部可访问, 而该语句没报错是
// 因为test方法也可以访问, 说明方法默认为public

echo $a->a; // 这里说明public属性外部也可以访问
$b = new b;
$b->test2(); // 这里说明public属性在子类中可以访问
echo $b->a;  // 这里说明public属性在子类外部也可以访问
?>

private(私有的)可以理解为只有对象的内部可以访问, 但是其中有可比较难理解的概念, 就是继承来的public方法可以访问到父类的private方法和属性, 而且实际上private属性和方法在技术上是无法被覆写的, 这个我目前还没有研究太透彻.

<?
class c{
	private $a;

	function __construct(){
		$this->a = "2";
	}

	function test(){
		echo $this->a;
	}
}

class d extends c{
	function test2(){
		echo $this->a;
	}
}

class e extends c{
	private $a="3";
	function test2(){
		echo $this->a;
	}
}

$c = new c;
$c->test();// 这里说明private属性对象内部可访问
// echo $c->a; // 这里会报错说明private属性外部不可以访问
$d = new d;
echo '[';
$d->test(); // 这里输出2,说明在test()中可以访问到class c 的$a
echo ']';
$d->test2(); // 这里没有产生输出说明private属性在子类中不可见
echo $d->a;  // 这里也没有产生输出说明private属性在子类外部也是不可见的
$e = new e;
echo '{';
$e->test();  // 这里输出2, 说明该方法可见, 但访问的是父类的$a
echo '}';
$e->test2();
// 这里输出了3说明$a被覆写了, 但其实在class e中
// 其父类的$a并不可见,所以并不是覆写而是创建
?>

protected (受保护的)我个人理解就是在对象和子对象中你想怎么用都可以, 就是不可以在外面用.

<?
class f{
	protected $a = "4";
	function test(){
		echo $this->a;
	}
}

class g extends f{
	function test2(){
		echo $this->a;
	}
}
$f = new f;
$f->test(); // 这里产生了输出,说明protected属性对象内部可以访问
//echo $f->a; // 这里报错说明protected属性对象外部不可以访问
$g = new g;
$g->test2(); // 这里输出4,说明protected属性在子类中可以访问
$g->test();  // 这里输出4,说明protected属性在子类中可以访问
// echo $g->a;  //这里报错,说明protected属性在子类的外部不可访问
?>

Sablog-X 1.6 => WordPress 2.2.3 转换程序 – 080422 测试版

Thursday, April 24th, 2008

这个转换程序终于算是完成了, 不过我只简单测试了一下, 欢迎各位网友进行测试.

我不建议菜鸟进行这个测试, 因为比较危险, 我当初转了2天, 试了不知道多少次才转过来, 虽然这个是全自动的, 但我也不敢保障, 如果有很需要转换而且觉得不把握的, 可以留言或者发email免费咨询, 如果觉得自己做不了的但很需要转的, 我可以提供收费援助.

注意: 使用前一定要备份! 一定 !!! 否则后果自负 !!!!!

__ 使用说明 __
准备事项:
1)备份要转换的sablog-x数据表及附件
2)准备一个本地php+mysql环境, 推荐xampp
3)创建程序目录结构如下
sa-wp/
sa-wp/sa/
sa-wp/wp/
4)分别在sa/和wp/下安装sablog-x 1.6和wordpress 2.2.3, 要转换其他版本的请对比一下版本之间数据库有没有改动, 没有才可以进行转换, 然后再升级wordpress就可以, 如果数据库结构不同, 那不好意思了. 注意sablog-x的表名前缀要和要转换的设置相同,sa和wp的表要放在同一数据库下.
5)将备份导入sablog-x, 将附件附件放到sablog-x内
6)将转换程序放在sa-wp/目录下

配置参数:
修改转换程序的设置,修改如下内容:

$s['hostname'] = ‘localhost’;    # 数据库地址
$s['username'] = ‘root’;    # 数据库帐号
$s['password'] = ”;        # 数据库密码
$s['dbname']   = ‘s-w’;        # 数据库名
$s['sa_pre']   = ‘sablog_’;    # sablog-x表名前缀
$s['wp_pre']   = ‘wp_’;        # wordpress表名前缀
$s['sa_dir']   = ‘sa/’;        # sablog-x安装目录
$s['wp_dir']   = ‘wp/’;        # wordpress安装目录
$s['wp_url']   = ‘http://www.foolbird.net/’;    # 网站访问地址, 注意后面加/

运行转换程序…

收尾工作:

1)进入wordpress后台, 或者使用phpmyadmin导出数据表内容
2)将空间上的sablog-x彻底删除. 全新安装wordpress 2.2.3, 将wp-content/uploads上传到服务器的wp-content下, 然后清空数据库, 导入刚刚导出的数据.

转换程序:

sa-wp_080422

当年我做过的面试题目

Wednesday, April 23rd, 2008

刚刚看了老陈准备的考试题, 是做留言本的, 所以想起了我以前做的一套面试题.

个人觉得这套题还是不错的, geel花了不少心思出的, 题先发出来, 答案整理过后再跟上.

__ 1.php __

__ 试题 __

XHTML和CSS方面的问题不允许借用dreamweaver之类的工具。

一、php方面

1、打开1.php,在文件里写一个类Test实现ITest接口。(如果不会实现接口可以直接改写成类)
2、在当前目录下写一个文件 1-1.php,依次调用你刚才写的Test类的所有method。
3、上述代码(interface ITest)中,public修饰符是什么意思?同类修饰符还有哪些?各有什么意义?
4、上述代码中,function前面为什么要加static关键字?php的关键字和函数区别大小写吗?
4.1、文件 1.php 中不添加结尾的 “?>” 可以运行吗?不添加 “?>” 有什么作用吗?
5、=== 和 == 有什么区别?
6、引用的利弊?一般来说各自在什么情况下用?function如何返回引用?如何给一个function传递引用?
7、一个典型web程序(例如一个论坛)的性能瓶颈通常来说在什么地方?一般采用什么什么方法来提高执行效率?
8、一般用什么办法判断当前页面是用户 post而不是get?

二、XHTML和CSS以及javascript方面
9、简述两条w3c关于XHTML1.0的规范
10、访问过的超链接样式不再具有css里定义的hover和active了,问题的原因可能是?解决方法是?
答案::visited
11、定义一个层,用css实现下列样式:高200px,宽300px,其边框宽度为1px,边框颜色为红色,背景颜色为蓝色,文字颜色为白色,文字水平和垂直居中,文字大小14px,粗体
12、设有 <ul><li>aaa</li><li>bbb</li></ul>,用css使aaa和bbb显示在同一行上。
答案:display:inline;
13、onblur事件在什么时机被触发?
答案:失去焦点
14、请指出body是什么元素的子元素?
答案:document
15、设有如下HTML代码:
<input type=”text” id=”companyName” />
<p id=”company”></p>
<input type=”button” onclick=”setCompanyName()” value=”设置公司名” />
请完成 setCompanyName() 方法,使点击按钮的时候,将<p>中的文字设置为输入框中的文字。如果点击按钮时输入框里没有文字,弹出“请输入文字”的提示。
16、使用过哪些js类库?

三、其他部分
17、使用过哪些发行版本的Linux?喜欢他们的哪些地方?
18、在linux下面你一般用什么方法安装一个软件?
19、bash下面 ls -lah 代表什么意思?
19、rm -i 代表什么意思?rm -f 呢?
20、你用什么办法登录到一台 linux 主机?21、一个文件的权限为 764,表示什么意思?用什么命令将这个文件的权限改为 700?
22、FTP传输过程中binary和ascii模式有什么区别?
23、一个ftp服务器ip为1.2.3.4,端口为123,用户名是 andy,密码是 xyz,要求下载 movie 目录下的 1.rm,请写出可以直接下载这个文件的 URL
24、HTTP返回代码中404代表什么含义?302呢?
25、<script src=”a.js?0607″></script>,请问为什要写问号及其后面的内容?
答案:防止缓存
26、假设第1题中某一个方法你不知道怎么实现,一般情况下你会通过哪些途径来解决?

CentOS+Apache+PHP+MYSQL+Python+Trac

Wednesday, April 16th, 2008

这个是我给公司配服务器时候做的记录, 先占个位置, 以后补全.

# CentOS 4.5

操作系统用的是CentOS 4.5 , 主要是因为CentOS不会有版权问题.

#
# MYSQL 5.0.5la
#
# root@localhost
#
shell> groupadd mysql
shell> useradd -g mysql mysql

shell> ./configure –prefix=/usr/local/mysql
shell> make
shell> make install
shell> cp support-files/my-medium.cnf /etc/my.cnf
shell> cd /usr/local/mysql
shell> chown -R mysql .
shell> chgrp -R mysql .
shell> bin/mysql_install_db –user=mysql
shell> chown -R root .
shell> chown -R mysql var
shell> bin/mysqld_safe –user=mysql &

#echo ‘/usr/local/mysql/bin/mysqld_safe –user=mysql &’ >> /etc/rc.local

Apache没有用2.2, 而是用了2.0, 比较稳定也足够用.

#
# APACHE 2.0.63
#
# DocumentRoot /usr/local/apache2/htdocs
#

shell> ./configure –prefix=/usr/local/apache2 –enable-dav –enable-dav-fs –enable-so –enable-rewrite
shell> make
shell> make install

#
# PHP 5.2.5
#

shell> ./configure –with-apxs2=/usr/local/apache2/bin/apxs –with-mysql=/usr/local/mysql –prefix=/usr/local/php5

shell> make
shell> make install
shell> cp php.ini-dist /usr/local/php5/lib/php.ini

shell> vim /usr/local/apache2/conf/httpd.conf

AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps

DirectoryIndex index.php index.html index.htm

AllowOverride All

/etc/rc.d/rc5.d/S97lamp

/usr/local/mysql/bin/mysqld_safe –user=mysql &
/usr/local/apache2/bin/apachectl start

下面这些东西是给php提供gd支持的.

#
# zlib 1.2.3
# freetype 2.1.10
# libpng 1.2.25
# jpeg-6b
# gd 2.0.33
#

tar zxvf zlib-1.2.3.tar.gz
cd zlib-1.2.3
./configure
make
make install

tar zxvf freetype-2.1.10.tar.gz
cd freetype-2.1.10
./configure –prefix=/usr/local/modules/freetype
make
make install

tar zxvf libpng-1.2.8-config.tar.gz
cd libpng-1.2.8-config
./configure
make
make install

tar zxvf jpegsrc.v6b.tar.gz
cd jpeg-6b
./configure –prefix=/usr/local/modules/jpeg6 –enable-shared –enable-static
make
make install

tar zxvf gd-2.0.33.tar.gz
cd gd-2.0.33
./configure –prefix=/usr/local/modules/gd –with-jpeg=/usr/local/modules/jpeg6 –with-png –with-zlib –with-freetype=/usr/local/modules/freetype
make
make install

先把目录建了, 要不编译的时候会找不到文件夹.

# mkdir jpeg6
# mkdir jpeg6/include
# mkdir jpeg6/lib
# mkdir jpeg6/bin
# mkdir jpeg6/man
# mkdir jpeg6/man/man1

shell> ./configure –with-apxs2=/usr/local/apache2/bin/apxs –with-mysql=/usr/local/mysql –prefix=/usr/local/php5 –with-iconv –with-mbstring –enable-mbstring –with-jpeg-dir=/usr/local/jpeg6/ –with-zlib –with-png –with-freetype-dir=/usr/local/freetype/ –with-gd=/usr/local/gd/

#
# Subversion 1.4.6
#

shell>./configure –prefix=/usr/local/subversion

一开始打算用mysql来存放账号密码的, 建好了数据表但是没有用.

CREATE DATABASE `svn`;
CREATE TABLE `user` (
`username` varchar(25) collate utf8_unicode_ci NOT NULL default ‘’,
`passwd` varchar(25) collate utf8_unicode_ci NOT NULL default ‘’,
`groups` varchar(25) collate utf8_unicode_ci NOT NULL default ‘’,
PRIMARY KEY (`username`),
KEY `groups` (`groups`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

#
# mod_python 3.3.1
#
./configure –with-apxs=/usr/local/apache2/bin/apx
make
make install

#
# clearsilver-0.10.5
#

shell>./configure –disable-apache –disable-csharp –disable-ruby –prefix=/usr/local/clearsliver –with-python

shell>make

shell>make install

shell>cd python/

PYTHON_SITE=’python -C \
“import sys; print [path for path in sys.path if path.find('site-packages') != -1][0]“‘

shell>python setup.py install

#
# mysql-python 1.2.2
#

set.cfg
修改mysql_config绝对路径
安全线程->false
shell>python setup.py build
shell>puthon setup.py install

#
# trac 0.11b2
#

# tar zxvf trac-0.10.4.tar.gz

# python ./setup.py install

# trac-admin /usr/local/trac/order initenv    (/usr/loca/trac 目录会自动创建)
#Project Name [My Project]> test
#Database connection string [sqlite:db/trac.db]> mysql://trac:trac@localhost/trac  //前面创建数据库所用的到信息
#Repository type [svn]>     //这里为空,直接回车
#Path to repository [/path/to/repos]> /var/svn/order   //SVN仓库地址

<Location /trac>
SetHandler mod_python
PythonHandler trac.web.modpython_frontend
PythonOption TracEnvParentDir /usr/local/trac
SetEnv PYTHON_EGG_CACHE /tmp
PythonOption TracUriRoot /trac
AuthType Basic
AuthName “test’s trac”
AuthUserFile /var/svn/passwd
Require valid-user
</Location>