今天加入了MeiJob,大概可以借词休息一下,跟外国人一起工作也许会简单许多,而且说英语的日子让虚荣心扑里啪啦的。
另外,Project Hashish已经开始,也许会有一个大发现,在MVC,多语言系统,URL Rewrite, Subversion,mashup, scrawler等各方面都将有长足的进步。
2007年3月30日星期五
2007年3月28日星期三
[+/-] |
PHP服务器变量 |
- “PHP_SELF”
-
当前正在执行脚本的文件名,与 document root 相关。举例来说,在 URL 地址为 http://example.com/test.php/foo.bar 的脚本中使用 $_SERVER['PHP_SELF'] 将会得到 /test.php/foo.bar 这个结果。__FILE__ 常量包含当前(例如包含)文件的绝对路径和文件名。
如果 PHP 以命令行方式运行,该变量在 PHP 4.3.0 之前无效。
- “argv”
-
传递给该脚本的参数。当脚本运行在命令行方式时,argv 变量传递给程序 C 语言样式的命令行参数。当调用 GET 方法时,该变量包含请求的数据。
- “argc”
-
包含传递给程序的命令行参数的个数(如果运行在命令行模式)。
- “GATEWAY_INTERFACE”
-
服务器使用的 CGI 规范的版本。例如,“CGI/1.1”。
- “SERVER_NAME”
-
当前运行脚本所在服务器主机的名称。如果该脚本运行在一个虚拟主机上,该名称是由那个虚拟主机所设置的值决定。
- “SERVER_SOFTWARE”
-
服务器标识的字串,在响应请求时的头信息中给出。
- “SERVER_PROTOCOL”
-
请求页面时通信协议的名称和版本。例如,“HTTP/1.0”。
- “REQUEST_METHOD”
-
访问页面时的请求方法。例如:“GET”、“HEAD”,“POST”,“PUT”。
注: 如果请求的方式是 HEAD,PHP 脚本将在送出头信息后中止(这意味着在产生任何输出后,不再有输出缓冲)。
- “REQUEST_TIME”
-
请求开始时的时间戳。从 PHP 5.1.0 起有效。
- “QUERY_STRING”
-
查询(query)的字符串(URL 中第一个问号 ? 之后的内容)。
- “DOCUMENT_ROOT”
-
当前运行脚本所在的文档根目录。在服务器配置文件中定义。
- “HTTP_ACCEPT”
-
当前请求的 Accept: 头信息的内容。
- “HTTP_ACCEPT_CHARSET”
-
当前请求的 Accept-Charset: 头信息的内容。例如:“iso-8859-1,*,utf-8”。
- “HTTP_ACCEPT_ENCODING”
-
当前请求的 Accept-Encoding: 头信息的内容。例如:“gzip”。
- “HTTP_ACCEPT_LANGUAGE”
-
当前请求的 Accept-Language: 头信息的内容。例如:“en”。
- “HTTP_CONNECTION”
-
当前请求的 Connection: 头信息的内容。例如:“Keep-Alive”。
- “HTTP_HOST”
-
当前请求的 Host: 头信息的内容。
- “HTTP_REFERER”
-
链接到当前页面的前一页面的 URL 地址。不是所有的用户代理(浏览器)都会设置这个变量,而且有的还可以手工修改 HTTP_REFERER。因此,这个变量不总是真实正确的。
- “HTTP_USER_AGENT”
-
当前请求的 User-Agent: 头信息的内容。该字符串表明了访问该页面的用户代理的信息。一个典型的例子是:Mozilla/4.5 [en] (X11; U; Linux 2.2.9 i586)。也可以使用 get_browser()得到此信息。
- “HTTPS”
-
如果脚本是通过 HTTPS 协议被访问,则被设为一个非空的值。
- “REMOTE_ADDR”
-
正在浏览当前页面用户的 IP 地址。
- “REMOTE_HOST”
-
正在浏览当前页面用户的主机名。反向域名解析基于该用户的 REMOTE_ADDR。
注: 必须配置 Web 服务器来建立此变量。例如 Apache 需要在 httpd.conf 中有 HostnameLookups On。参见 gethostbyaddr()。
- “REMOTE_PORT”
-
用户连接到服务器时所使用的端口。
- “SCRIPT_FILENAME”
-
当前执行脚本的绝对路径名。
注: 如果脚本在 CLI 中被执行,作为相对路径,例如 file.php 或 ../file.php,$_SERVER['SCRIPT_FILENAME'] 将包含用户指定的相对路径。
- “SERVER_ADMIN”
-
该值指明了 Apache 服务器配置文件中的 SERVER_ADMIN 参数。如果脚本运行在一个虚拟主机上,则该值是那个虚拟主机的值。
- “SERVER_PORT”
-
服务器所使用的端口。默认为“80”。如果使用 SSL 安全连接,则这个值为用户设置的 HTTP 端口。
- “SERVER_SIGNATURE”
-
包含服务器版本和虚拟主机名的字符串。
- “PATH_TRANSLATED”
-
当前脚本所在文件系统(不是文档根目录)的基本路径。这是在服务器进行虚拟到真实路径的映像后的结果。
注: PHP 4.3.2 之后,PATH_TRANSLATED 在 Apache 2 SAPI 模式下不再和 Apache 1 一样隐含赋值,而是若 Apache 不生成此值,PHP 便自己生成并将其值放入 SCRIPT_FILENAME 服务器常量中。这个修改遵守了 CGI 规范,PATH_TRANSLATED 仅在 PATH_INFO 被定义的条件下才存在。
Apache 2 用户可以使用 httpd.conf 中的 AcceptPathInfo On 来定义 PATH_INFO。
- “SCRIPT_NAME”
-
包含当前脚本的路径。这在页面需要指向自己时非常有用。__FILE__ 包含当前文件的绝对路径和文件名(例如包含文件)。
- “REQUEST_URI”
-
访问此页面所需的 URI。例如,“/index.html”。
- “PHP_AUTH_DIGEST”
-
当作为 Apache 模块运行时,进行 HTTP Digest 认证的过程中,此变量被设置成客户端发送的“Authorization”HTTP 头内容(以便作进一步的认证操作)。
- “PHP_AUTH_USER”
-
当 PHP 运行在 Apache 或 IIS(PHP 5 是 ISAPI)模块方式下,并且正在使用 HTTP 认证功能,这个变量便是用户输入的用户名。
- “PHP_AUTH_PW”
-
当 PHP 运行在 Apache 或 IIS(PHP 5 是 ISAPI)模块方式下,并且正在使用 HTTP 认证功能,这个变量便是用户输入的密码。
- “AUTH_TYPE”
-
当 PHP 运行在 Apache 模块方式下,并且正在使用 HTTP 认证功能,这个变量便是认证的类型。
2007年3月27日星期二
[+/-] |
使用MaxMind 根据IP地址对访问者定位 |
有时你需要知道你的站点访问者来自哪个国家——比如如果你正打算执行针对地理区域的广告计划。本文将对此方法进行介绍。 有时你需要知道你的站点访问者来自哪个国家——比如如果你正打算执行针对地理区域的广告计划。这正是象MaxMind's GeoIP一类的工具大显身手的地方——它可以让你从访问者的IP地址轻松获取其确切的地理位置信息。 MaxMind提供了商业数据库和免费数据 库。前者更为精确,精度可以达使用者所在城市信息一级,而后者则只能确定国家和地区。在本文中,我们将演示免费版的使用方法。如果你需要更多详细信息,比 如远程客户的城市以及国家信息,你需要从MaxMind:http://www.maxmind.com购买更详细的数据库。 起步 要使用此软件,你必须首先下载GeoIP免费国家信息文件:http://www.maxmind.com/app/geoip_country 并将其存放于Web服务器的某个目录中。然后你需要选择数据库文件所使用的语言API。为简化整个过程,我们将使用纯粹的PHP版本以避免其他额外的配置 或设置Apache组件。请记住在安装软件到Web站点前阅读软件许可证条款:http: //www.maxmind.com/download/geoip/database/LICENSE.txt以确保你同意这些条款。 代码列表A // include functions include("geoip.inc"); // read GeoIP database $handle = geoip_open("GeoIP.dat", GEOIP_STANDARD); // map IP to country echo "IP address 62.149.130.132 located in " . geoip_country_name_by_addr($handle, "62.149.130.132") . " (country code " . geoip_country_code_by_addr($handle, "62.149.130.132") . ")"; // close database handler geoip_close($handle); // print compulsory license notice echo " -- This product includes GeoIP data created by MaxMind, available from http://maxmind.com/ --"; ?> 列表A中的代码显示了使用模块(geoip.inc)以访问GeoIP免费国家信息数据库(GeoIP.dat)的基本方法。示例假设PHP include和国家家信息数据库文件都在与PHP文件本身相同的目录中。如果示例与你的安装不同,则需要根据需要改变路径。 示例代码相当明了,在引入GeoIP PHP函数库后,第一步即使用geoip_open()函数打开GeoIP数据库文件。此函数接收两个参数:数据库文件路径和数据库类型。 我们然后使用由调用geoip_open()返回的句柄,由此根据所给的IP地址以获取两字母的国家代码及直观的国家名称。其中还要分别借助函数 geoip_country_code_by_addr()和geoip_country_code_by_name()。二者都接收两个参数:由 geoip_open()返回的句柄以及需要解析的IP地址。 一旦获得所需信息,我们通过调用geoip_close()关闭数据库文件。
// www.knowsky.com
[+/-] |
正则表达式中的特殊字符 |
字符 描述
\
将下一个字符标记为一个特殊字符、或一个原义字符、或一个后向引用、或一个八进制转义符。例如,'n' 匹配字符 "n"。'\n' 匹配一个换行符。序列 '\' 匹配 "" 而 "\(" 则匹配 "("。
^
匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性,^ 也匹配 '\n' 或 '\r' 之后的位置。
$
匹配输入字符串的结束位置。如果设置了RegExp 对象的 Multiline 属性,$ 也匹配 '\n' 或 '\r' 之前的位置。
*
匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。 * 等价于{0,}。
+ 匹配前面的子表达式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,}。
?
匹配前面的子表达式零次或一次。例如,"do(es)?" 可以匹配 "do" 或 "does" 中的"do" 。? 等价于 {0,1}。
{n}
n 是一个非负整数。匹配确定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的两个 o。
{n,}
n 是一个非负整数。至少匹配n 次。例如,'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "foooood" 中的所有 o。'o{1,}' 等价于 'o+'。'o{0,}' 则等价于 'o*'。
{n,m}
m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。刘, "o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?'。请注意在逗号和两个数之间不能有空格。
?
当该字符紧跟在任何一个其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串 "oooo",'o+?' 将匹配单个 "o",而 'o+' 将匹配所有 'o'。
.
匹配除 "\n" 之外的任何单个字符。要匹配包括 '\n' 在内的任何字符,请使用象 '[.\n]' 的模式。
(pattern)
匹配pattern 并获取这一匹配。所获取的匹配可以从产生的 Matches 集合得到,在VBScript 中使用 SubMatches 集合,在JScript 中则使用 {CONTENT}… 属性。要匹配圆括号字符,请使用 '\(' 或 '\)'。
(?:pattern)
匹配 pattern 但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用 "或" 字符 (|) 来组合一个模式的各个部分是很有用。例如, 'industr(?:y|ies) 就是一个比 'industry|industries' 更简略的表达式。
(?=pattern)
正向预查,在任何匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如, 'Windows (?=95|98|NT|2000)' 能匹配 "Windows 2000" 中的 "Windows" ,但不能匹配 "Windows 3.1" 中的 "Windows"。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。
(?!pattern)
负向预查,在任何不匹配Negative lookahead matches the search string at any point where a string not matching pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如'Windows (?!95|98|NT|2000)' 能匹配 "Windows 3.1" 中的 "Windows",但不能匹配 "Windows 2000" 中的 "Windows"。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始
x|y
匹配 x 或 y。例如,'z|food' 能匹配 "z" 或 "food"。'(z|f)ood' 则匹配 "zood" 或 "food"。
[xyz]
字符集合。匹配所包含的任意一个字符。例如, '[abc]' 可以匹配 "plain" 中的 'a'。
[^xyz]
负值字符集合。匹配未包含的任意字符。例如, '[^abc]' 可以匹配 "plain" 中的'p'。
[a-z]
字符范围。匹配指定范围内的任意字符。例如,'[a-z]' 可以匹配 'a' 到 'z' 范围内的任意小写字母字符。
[^a-z]
负值字符范围。匹配任何不在指定范围内的任意字符。例如,'[^a-z]' 可以匹配任何不在 'a' 到 'z' 范围内的任意字符。
\b
匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。
\B
匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。
\cx
匹配由x指明的控制字符。例如, \cM 匹配一个 Control-M 或回车符。 x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 'c' 字符。
\d
匹配一个数字字符。等价于 [0-9]。
\D
匹配一个非数字字符。等价于 [^0-9]。
\f
匹配一个换页符。等价于 \x0c 和 \cL。
\n
匹配一个换行符。等价于 \x0a 和 \cJ。
\r
匹配一个回车符。等价于 \x0d 和 \cM。
\s
匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。
\S
匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。
\t
匹配一个制表符。等价于 \x09 和 \cI。
\v
匹配一个垂直制表符。等价于 \x0b 和 \cK。
\w
匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]'。
\W
匹配任何非单词字符。等价于 '[^A-Za-z0-9_]'。
\xn
匹配 n,其中 n 为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如, '\x41' 匹配 "A"。'\x041' 则等价于 '\x04' & "1"。正则表达式中可以使用 ASCII 编码。.
\num
匹配 num,其中 num 是一个正整数。对所获取的匹配的引用。例如,'(.)' 匹配两个连续的相同字符。
\n
标识一个八进制转义值或一个后向引用。如果 \n 之前至少 n 个获取的子表达式,则 n 为后向引用。否则,如果 n 为八进制数字 (0-7),则 n 为一个八进制转义值。
\nm
标识一个八进制转义值或一个后向引用。如果 \nm 之前至少有is preceded by at least nm 个获取得子表达式,则 nm 为后向引用。如果 \nm 之前至少有 n 个获取,则 n 为一个后跟文字 m 的后向引用。如果前面的条件都不满足,若 n 和 m 均为八进制数字 (0-7),则 \nm 将匹配八进制转义值 nm。
\nml
如果 n 为八进制数字 (0-3),且 m 和 l 均为八进制数字 (0-7),则匹配八进制转义值 nml。
\un
匹配 n,其中 n 是一个用四个十六进制数字表示的 Unicode 字符。例如,\u00A9 匹配版权符号 (?)。
2007年3月19日星期一
[+/-] |
判定mine类型的东西 |
$filetype=array();
$filetype['hqx']="application/mac-binhex40";
$filetype['bin']="application/octet-stream";
$filetype['oda']="application/oda";
$filetype['pdf']="application/pdf";
$filetype['ai']="application/postsrcipt";
$filetype['eps']="application/postsrcipt";
$filetype['es']="application/postsrcipt";
$filetype['rtf']="application/rtf";
$filetype['mif']="application/x-mif";
$filetype['csh']="application/x-csh";
$filetype['dvi']="application/x-dvi";
$filetype['hdf']="application/x-hdf";
$filetype['nc']="application/x-netcdf";
$filetype['cdf']="application/x-netcdf";
$filetype['latex']="application/x-latex";
$filetype['ts']="application/x-troll-ts";
$filetype['src']="application/x-wais-source";
$filetype['zip']="application/zip";
$filetype['bcpio']="application/x-bcpio";
$filetype['cpio']="application/x-cpio";
$filetype['gtar']="application/x-gtar";
$filetype['shar']="application/x-shar";
$filetype['sv4cpio']="application/x-sv4cpio";
$filetype['sv4crc']="application/x-sv4crc";
$filetype['tar']="application/x-tar";
$filetype['ustar']="application/x-ustar";
$filetype['man']="application/x-troff-man";
$filetype['sh']="application/x-sh";
$filetype['tcl']="application/x-tcl";
$filetype['tex']="application/x-tex";
$filetype['texi']="application/x-texinfo";
$filetype['texinfo']="application/x-texinfo";
$filetype['t']="application/x-troff";
$filetype['tr']="application/x-troff";
$filetype['roff']="application/x-troff";
$filetype['shar']="application/x-shar";
$filetype['me']="application/x-troll-me";
$filetype['ts']="application/x-troll-ts";
$filetype['gif']="image/gif";
$filetype['jpeg']="image/pjpeg";
$filetype['jpg']=array("image/pjpeg","image/jpeg");
$filetype['jpe']="image/pjpeg";
$filetype['ras']="image/x-cmu-raster";
$filetype['pbm']="image/x-portable-bitmap";
$filetype['ppm']="image/x-portable-pixmap";
$filetype['xbm']="image/x-xbitmap";
$filetype['xwd']="image/x-xwindowdump";
$filetype['ief']="image/ief";
$filetype['tif']="image/tiff";
$filetype['tiff']="image/tiff";
$filetype['pnm']="image/x-portable-anymap";
$filetype['pgm']="image/x-portable-graymap";
$filetype['rgb']="image/x-rgb";
$filetype['xpm']="image/x-xpixmap";
$filetype['txt']="text/plain";
$filetype['c']="text/plain";
$filetype['cc']="text/plain";
$filetype['h']="text/plain";
$filetype['html']="text/html";
$filetype['htm']="text/html";
$filetype['htl']="text/html";
$filetype['rtx']="text/richtext";
$filetype['etx']="text/x-setext";
$filetype['tsv']="text/tab-separated-values";
$filetype['mpeg']="video/mpeg";
$filetype['avi']="video/avi";
$filetype['rm']="video/rm";
$filetype['rmvb']="video/rmvb";
$filetype['wmv']="video/x-ms-wmv";
$filetype['flv']="application/octet-stream";
$filetype['mpg']="video/mpeg";
$filetype['mpe']="video/mpeg";
$filetype['avi']="video/x-msvideo";
$filetype['qt']="video/quicktime";
$filetype['mov']="video/quicktime";
$filetype['moov']="video/quicktime";
$filetype['movie']="video/x-sgi-movie";
$filetype['au']="audio/basic";
$filetype['mp3']="audio/mp3";
$filetype['snd']="audio/basic";
$filetype['wav']="audio/wav";
$filetype['wma']="audio/x-ms-wma";
$filetype['aif']="audio/x-aiff";
$filetype['aiff']="audio/x-aiff";
$filetype['aifc']="audio/x-aiff";
$filetype['swf']="application/x-shockwave-flash";
$filetype['doc']="application/msword";
$filetype['ini']='application/octet-stream';
?>
[+/-] |
在PHP里通过工厂模式提高效率【转】 |
这文章说的很透彻,对工厂模式的理解是非常有帮助的。当然如果想深入了解设计模式,可以看我们翻译的《PHP设计模式导论》
【原文地址】:http://www.phpchina.com/bb...
在进行大型系统的开发的时候,我总是困饶,是否应该包含每一个可能用到的类库文件。
如果只是在使用中才包含,会给开发带来很大的麻烦。因为我不可能预先知道在哪个地方会使用到哪个类。而且,如果在每个页面中,根据需要进行require 或include,这是令人很头疼的,我们往往会因为忘记include而导致一个warning或fatal。
如果在一个全局文件中包含所有的类库,然后所有的页面都包含这个全局文件。这样,虽然简化了include的工作,但是却带来了效率的下降。因为php会对每一个包含在内的文件进行检测。虽然PHP的效率很高,但是检测一大堆的类,还是会带来一些性能的下降的,特别是在一个大型系统中。
是不是有方法可以两全其美呢?肯定有了,不然我就不打这么多字了。
方法就是工厂模式。具体工厂模式是什么,我就不说了,这个已经被程序员们说到烂了。
我们建立以下四个文件
index.php
include_once("f.inc.php");
$f=new factory;
$t1=&$f->create('T1');
echo $t1->getName();
echo $config;
?>
f.inc.php
class factory
{
function factory()
{
$this->mClasses=array('T1'=>'t1.inc.php','T2'=>'t2.inc.php');
}
function &create($class)
{
if (!class_exists($class))
{
require_once($this->mClasses[$class]);
}
return new $class;
}
}
?>
t1.inc.php
global $config;
$config='surfchen';
class T1
{
var $mName='name::T1';
function getName()
{
return $this->mName;
}
}
?>
t2.inc.php
class T2
{
function T2()
{
echo 't2 is ok';
}
}
?>
在index.php里,我们通过一个factory类来创建其他的类实例。
在factory里,保存有一个数组$this->mClasses,格式为array(”类名”=>”类文件路径”).
我们通过factory::create()来创建一个类实例的时候,在create()里,会首先检测类是否存在,如果不存在,就根据$this->mClasses把类对应的类文件包含进来。然后创建并返回一个该类的实例。
这样,我们只需要把factory类文件包含进执行的脚本(如index.php)中就可以了。
大家可能还注意到了在t1.inc.php中的这两行代码。
global $config;
$config=’surfchen’;
为什么需要global呢?因为t1.inc.php是在factory::create中被包含的,t1文件中的变量将会默认为create的函数级变量。所以我们需要对其中的变量(如$config)进行global以便index.php能访问到。
运行index.php,将会输出
name::T1surfchen
[+/-] |
互联网盈利模式思考 |
转载于:it草根网
K12网站从1999年创办,2000年春节就遇上Nasdaq大崩盘,因而被迫转向传统业务–教育信息化软件,一直到2005年中时,传统业务不断萎缩,才开始再次探索通过网站挣钱的方向。
试图重新通过网站挣钱–或者说搞“网络经济”,对于K12来说,倒并不是如何度过初创期的问题,也不是吸引访问量或者吸引用户的问题,投入虽然不足,但由于网下业务仍然在持续开展,因此还是有一定资金支撑的。因此,现在对于K12来说,只是怎样通过用户、访问量来挣到钱的问题。前面几篇文章就是立足于此。
(当然还有一条路子,就是先找到资金,然后再进一步扩大影响,最后再考虑挣钱。但这条路子对于猫扑、ChinaBBS这样的大众化网站来说,或许还能行得通, 可是对于K12这样的专业网站来说,网站本身的影响力似乎很难大到足够引起投资者的注意。更为现实的路子或许是自己找到可行的商业模式,然后再去找投资者。)
所以,正如我在前面的文章中提到的:创意->产品开发->市场推广每个环节都是非常重要的。而在网络经济中,让众多的用户知道你、相信你是一件很难的事情,但背后的商业模式也不是件容易的事情。就象许多人都曾经表达过的:互联网的商业模式在刚开始的阶段是无法看清楚的。大家一拥而上搞门户网站时,本来都觉得广告是最挣钱的,没想过最后居然是无线增值业务和网游最挣钱–包括华尔街在内。
以下引用记者采访的陈一舟只言片语,也是类似的意思。
———————————-
记者:你认为像猫扑、Donews或者是Dudu.com网站,他的广告的盈利来源主要是还是广告吗?或者是未来有更多的利润的方向,现在看得清楚的好象就是广告。
陈一舟:广告看的很清楚了,其他的盈利模式我觉得未来几年广告还是为主,但是过了三年以后,我不知道是不是去收费,但是我对互联网的理解,我觉得互联网上的东西最后还是以广告为主,其他都要变成免费的。千万不要小看广告的生意,因为广告已经造就了Google的全世界的地位。他的市值已经超过了时代华纳。不要小看广告,广告是小但是成长量比较大。而且他能为广告客户带来比较高的价值。
记者:我理解您刚才说的不管是Donews或者是猫扑一开始都没有考虑赚钱的问题,都是先把人气做旺,就好象把人气造起来以后,无论是靠广告或者是其他的业务赚钱,就像Google一样用的人多了赚钱的渠道自然就来了。
陈一舟:至少在互联网上应该是这样。我觉得社区的变量也比较大,至少是中上的。
记者:上海有一个这样的网站,叫做迈克(英文).com据说他已经有一万多人的真实的白领的资料。已经有些人看上他了,可能这就是他的价值吧。
陈一舟:对。
———————————
目前来看,有一点是肯定的:只要你能吸引到“足够多”的用户–比如象盛大、QQ一样拥有1亿以上的用户水平,就比较容易把用户变成钱了。换句话来说,新浪、搜狐、网易、TOM、QQ这些网站已经有足够的能力把注意力转化为金钱。
当然,实际上也没有几个网站有足够的能力、金钱、耐性和运气能够吸引到上亿用户,尤其是许多“垂直门户”、“专业网站”(如斗牛士、榕树下、K12等),还有一些区域性的网站–比如分类信息网站(如58同城、客齐集之类的),是不太可能做到这么大的用户量和访问量的。
因此,在“注意力”还不够的情况下,而且又没有足够的资本支撑你到有足够注意力的那一天的话,即使你有很多用户、在目标用户群中有很大的影响力、你的品牌在目标用户群中很响亮,但如何把影响力变成钱仍然是一件很难的事情。
以目前的网站赢利手段来说,公认的大规模商业模式只有3种:广告、无线增值、网游,其它规模相对较小的还有会员费、电子商务(网上买卖)、虚拟物品交易、增值服务等几种。
按照不同的性质,这些业务应该可以分为4种模式。
(1)免费业务 + 第三方增值服务。比如网络广告、……。
(2)免费业务 + 基于免费业务的增值服务。比如无线增值服务、虚拟物品交易(比如赛我网、QQ秀的个人形象道具,网络游戏道具买卖等)、其它网络增值服务(如QQ网络硬盘扩容、QQ特号等)。
(本Blog刚转载的一位风险投资商的“我最喜欢的商业模式”,恰好与此点完全相符。)
(3)直接收费的网络服务(或许可免费体验)。比如网游、各种交易平台(如alibaba、ebay)、UUTV网络电视频道包月、EngilshTown网上英语培训等。
(4)网上通道,网下服务(收费,但业务主要依靠传统经济开展)。传统的“电子商务”概念基本上应该指这一条。比如各种网上书店、携程网、唐高网(整合高尔夫球场资源)等。
在上述4种类型中,我们以业务本身是免费/收费、付费方是第三方/用户、赢利方式是通过网上/网下进行了划分。这样划分的好处就是可以比B2B、B2C、 C2C这样简单地以用户性质的划分方式思考起来更贴近网站的实际特性。当然,这4种类型业务当然也可以交叉起来,形成更为丰富的特性。
由于这里的内容非常丰富,也有相当典型的实例,因此后面将逐个重点探讨。
上文说到互联网业务的4种模式。其实无论是哪一种–尤其是前三种,其基本的规律都是“免费+收费”,而且即使收费,其金额相对来说也要足够地小。因为在互联网上开展的业务,对于用户来说既无法实地感知、又不见得一定要来,因此免费就是非常重要的。
免费业务对两个方面都有重要帮助:建立用户认知、培养用户习惯。这其实也是现代商业社会中普遍的商业规律。用户不知道你、不知道要做这件事,就不可能购买– 从而无法做任何经营活动;用户不习惯于做,就不会产生重复购买–从而无法产生源源不断的利润。可以说,没有这种“认知”和“习惯”,就没有商业。
因此,在现实生活中,无论是可口可乐、还是牙刷牙膏、保健品,从中央电视台的广告,到赞助各种赛事,到各种各样的研究成果“表明……”,都是希望先让我们先了解、感觉到能接受或有必要,最后慢慢变成习惯。比如:牙刷要3个月一换,穿名牌就会很“酷”之类的。
网络上培养用户认知和习惯的主要途径就是“免费”。比如:刚开始时我们不觉得一定要去网上看新闻,也不一定要通过MSN聊天。但培养了几年,几天上不了网就觉得信息极为不通畅,与朋友也不能随时联系了,这时,我们不仅觉得这样的网络服务有用,而且已经“习惯于用”了。既然你离不开了,这项服务对你来说就是有价值了,这时让你再付一定的费用,想必你不会拒绝。
而对于最后一种模式来说,免费的可能性就会小一些–因为其主要收入来源是网下业务,而网下业务免费,就意味着你要付出较高的成本。这一点不象网上的业务,对用户免费的“增量成本”往往很小–这也可以说是网上业务的优势吧。
当然,最后一种模式的重点本质上并不在于“免费”,因为其收入来源是网下业务,换句话来说是用户本来就需要的产品或服务,只不过通过网上来出售而已。因而,其最需要的是“给用户带来的明确价值”–通常来说是省钱、省事,当然还有用户对你服务水平的认可和信心。
其实,在现实的网下商业现象中,也有不少用“免费”或近似于免费的概念吸引用户、最终从用户人气中获取销售的。这里举一个例子。
这个例子是发生在我所住的天通苑小区的。天通苑小区由于人极多–据说有20万人,而且这里的老人特别集中,因此吸引了很多做健康/保健用品生意的厂家。但是大家都知道:老人买东西是极为谨慎的,而且以低值商品为主,那么怎么能让老人来买价值几千元、几万元的高档产品呢?也许大家都已经在身边见到了他们的做法:免费–每天都可以免费使用,也不动员或要求你买,你觉得有用就可以每天来用,只要你不想买,就可以永远不买。结果呢?象我父母每天都要排队去做的一种仪器–现在已经免费做3年了吧,叫“科治好”,据说是净化血液的,效果应该是很好的,售价2万多,一个这样的免费体验中心,每个季度就可以卖出20台以上。这也是通过免费吸引用户,建立用户认知、习惯,最后实现销售的典型案例。
还有一个小例子是听到广播中的广告,说是1块钱可以买到一瓶某种保健食品(比如深海鱼油、卵鳞脂之类的),限一人购一瓶,说是希望每个人都能够以1元钱的价钱感受到优质服务。–可想而知,你体会到了,如果感觉到效果确实不错,再加上些许动员,恐怕有相当比例的人会继续购买的。
其实,无论是网上还是网下,只要是做商业,其基本原理都是相通的。让人们花钱,人们总是会犹豫的。只要用户犹豫一下,90%的销售机会就溜走了。而免费、或近似于免费,则非常容易获得大量关注和潜在用户,能够培养用户认知甚至习惯,这里一定会有一定比例的用户转化为真正的“客户”的–只是一个转化率问题,而且必定存在一个转化率。比如,即使在网站上做广告,其转化率的典型值是:0.5%的点击率、每次点击0.10元左右。
当然,不管是网上还是网下,你敢让用户免费体验的前提就是:你的产品和服务一定要过硬!只要有这个前提,就可以充分利用“免费”(或近似于免费)这个有力的武器–当然产品形式必必须要适合于免费,迅速获取较大数量的潜在目标用户。一旦获得了大量用户,下面的工作只是跟踪用户、争取较高的转化率而已。这样,市场宣传工作的成本大大降低了,而且销售工作的跟进也就是顺理成章的事。
“免费”+“转化率”,这就是互联网营销中的一个有别于传统营销的常用手段。
[+/-] |
URL映射 |
1、大家来说说URL映射吧
一般url映射有两种方式,一种是通过mod_rewrite实现,这种网上教材很多我也不多说了。另外一种是在程序中模拟,比如类似zend Framework中的那种方式/index.php/controller/action/var1/value1/var2/value2/。这里方式其实最主要是通过一个统一的输入接口,然后对url进行解析,最后转发到相应的controller中的module。
我这里写了两个简单函数来模拟。
第一个函数主要是进行地址解析,把类似/index.php/controller/action/var1/value1/var2/value2/的地址解析出来,一般来说要解析成三部分:controller,module,params。
/**
*对url路由进行简单的解析,支持对/path/to/site/index.php/module/action/parm/value
* /path/to/site/index.php?/module/action/parm/value和
* /path/to/site/?/module/action/parm/value三种形式的处理
*@param:null
*@return:router array
*/
function url_router(){
$path=strip_tags($_SERVER['REQUEST_URI']);
$strpos=strpos($path,'.php');
if($strpos){
$path=substr($path,$strpos+4);
}else{
if(empty($_SERVER['QUERY_STRING'])){
$strpos=strpos($path,'?');
if($strpos){
$path=substr($path,$strpos+1);
}else{
$path='';
}
}else{
$path=$_SERVER['QUERY_STRING'];
}
}
//统一化$path的格式,如果$path的第一个字符为/则去掉
if($path[0]=='/'){
$path=substr($path,1);
}
//解析,并且路由
if(!empty($path)){
$path=explode('/',$path);
$router['controller']=$path[0];
$router['action']=(!empty($path[1]))?$path[1]:'index';
//print_r($path);
for($i=2;$i
}
$router['params']=$params;
}else{
//默认路由信息
$router['controller']='index';
$router['action']='index';
$router['params']=array();
}
return $router;
}
?>
这里就完成主要的url解析功能,然后是转发映射,下面这个函数实现(注意这个函数的实现是结合了我自己的架构,所以你采用的话需要相应的修改,当然你的MVC如果类似zend Framework,那应该要该的不多。)
function url_dispatch($router,$app_path='/app/controllers/')
{
require_once(SERVER_PATH.'/libs/controller.class.php');
$controller=$router['controller'].'Controller';
//echo SERVER_PATH.$app_path.$controller.'.class.php';
if(!file_exists(SERVER_PATH.$app_path.$controller.'.class.php'))die('缺少必要的类!');
require_once(SERVER_PATH.$app_path.$controller.'.class.php');
$controller=new $controller();
$controller->_setParam($router['params']);
$controller->{$router['action'].'Action'}();
return true;
}
?>
2007年3月16日星期五
[+/-] |
DIGG下的赋值的探讨[转] |
From:http://blog.donews.com/BearEyeOnIT/archive/2007/03/13/1139702.aspx
看了板儿砖的CNSNS的《DIGG下的赋值初探》,也想谈谈自己对digg类网站的赋值的一些宏观上的想法,微观的具体到使用哪些参数,各参数比重等细节本文就不深入下去了。
正如CNSNS文章中提到整个赋值体系分为两部分:一、基于信息内容轴的赋值,即对每一篇文章的赋值;二、基于用户行为轴的赋值,即对每一个用户进行赋值。这两部分又相互结合,一部分设计的不好也会影响到另外一部分的效果。
整个赋值系统的最终目标就是使得优秀的文章能被推荐出来给更多人阅读,同时系统也应该具有抗作弊性,不能让少数人的不正常行为影响到最终的结果。
我 先来探讨下关于文章的赋值。一篇文章的赋值是由参与评价的所有用户决定的,但是由于用户本身的赋值有所差异,所以用户的评价行为对文章的赋值的改变应该也 有一定的差异。比如:对于低于赋值x的用户,其影响力设为0,这样可以很好的限制某些人通过注册众多的帐号来作弊的行为。对高于赋值y的用户设定其影响力 为1,对于赋值在x和y之间的用户其影响力呈线性在0-1之间变化。
简单的,文章的赋值=叫好的用户总影响力-拍砖的用户的影响 力。但是考虑到一些文章可能相对有争论性,较能引起大家的关注讨论,所以更进一步的文章赋值公式可以修正为:文章赋值=m*(叫好值-拍砖值)+n*(总 参与用户讨论数)。系数m、n决定了它们的比重。修正后的公式能使一些毁誉参半的观点想法的文章也能有高的赋值,从而被更多人关注。
下面谈 谈关于用户的赋值。正如前面设定,用户低于赋值x时其对文章影响力为0。那么用户就需要通过其在网站上的交互活动来提升他的赋值,以达到对文章产生影响力 的地位。这也相对可以促进用户参与网站交互的积极性。用户可以通过发文章,评价文章来获得赋值。可以给评价文章获得的赋值设定较小的值。而用户发文章以 后,这篇文章的含金量将会同值赋给用户,这样就可以刺激用户多发有价值的文章,而不是简单的转贴子,灌水。
可以看到,文章的赋值会影响到发文章用户的赋值,用户的赋值又影响到他评论的文章的赋值。这两部分相互关联,是一个有机整体,所以设计的时候也不应该简单的把两个割裂开来。