| jimmy's profileJDlogPhotosBlogLists | Help |
|
September 15 恢复对运营和产品的关注恢复对运营和产品的关注
自我感觉,我对于自己的状态还是比较了解的,对非技术的关注减少确实是非我情愿所致。因为长期以来,产品、运营甚至销售对技术的需求是社区最迫切解决的问题。去年底层改进后带来的PV繁荣,掩盖了PV导向匆忙改版留下的众多隐患,而技术人员被忙乱的湮没在层出不穷的新需求中。技术部门的工作困难程度和承担的工作压力其实是很多人并不了解的。所以,提高工作效率,控制技术成本,对我而言是当时最重要的任务。由过去无序的繁忙转变为现在有序的繁忙,还算是初见成效的。非常感谢组内成员的共同努力,现在终于能够有点时间考虑技术之外的东西了。 事实上,从上个月末开始,已经逐渐为非技术部分划出更多的精力,与产品人员的交流也比以往增多了。最近两周,我坚持每天用两个小时来看社区的内容,看内容的特点,看社区的特点,看用户的行为特点,来不断更新自己已经老旧了的思路和理念,不断反思自己对用户的判断是否已经有了偏差。 互连网的变化是非常快的,可能很多分析和经验,在半年或者一年后就已经完全不适用了。而我真正混在社区里面,真正在社区中浸淫已经是很多年以前了。当真正静下心来再去看今天的社区,确实有很多已经不同了。这段时间,对很多数据进行了分析,尤其是对页面点击,很多分析结果与我的主观判断有很大出入。比如,通常广告价格第二屏、第三屏是2:1,谈判时能把第三屏争取成第二屏也会是很成功。但是,统计的结果显示,第二屏跟第三屏并无区别。是社区的特点?还是因为版式?更新观念的同时,也会引发更多思考。 当初为工作开这个博客的时候,特意设置了一个分类叫“触类旁通”,目的就是分析和研究更多与技术并不直接相关的东西。非常惭愧,这个分类下面现在还基本是空的。事实上,这种触类旁通的思考和学习是非常重要的,尤其是在因果不明晰情况下要作出判断的时候,借鉴或者是灵感触发的作用就会非常有意义。年底之前,计划跟踪20个网站,深入分析5个。从技术角度去看产品和模式及其运营,可能跟Donews上有很多不同。希望届时可以有更多东西跟大家分享。 另外,在跟别人探讨的时候,谈了很多“本体价值”的想法。交流的过程中,自己对本体价值的概念也比以前明晰了很多。在以后会找时间把这个想法系统的描述出来。
参考:Iconv的编码列表参考:Iconv的编码列表
It has also some limited support for transliteration, i.e. when a character cannot be represented in the target character set, it can be approximated through one or several similarly looking characters. Transliteration is activated when "//TRANSLIT" is appended to the target encoding name.
~~呵呵~~ SQLite研究——自定函数SQLite研究——自定函数
jimmy | 14 九月, 2006 14:28 SQLite是一个轻量级引擎,尤其在PHP中内置的2版本,并不带有类似MySQL那样的实用函数。
但是它提供了一套非常灵活的自定义函数方式。用户可以将需要使用的功能,先用PHP函数实现,然后注册到SQLite里面,就可以在SQL语句中使用了。
一个最简单的例子:
function url2host($url) { $parts = parse_url($url); return "$parts[scheme]://$parts[host]"; } // Tell SQLite to associate PHP function url2host( ) with the // SQL function host( ). Say that host( ) will only take 1 argument. sqlite_create_function($db, 'host', 'url2host', 1); // Do the query $r = sqlite_query($db, 'SELECT DISTINCT host(lower(url)) AS clean_host FROM access_log ORDER BY clean_host;'); SQLite只支持Count,不支持Averag。所以类似功能也要写函数实现。 因为需要对多项结果进行累加,注册方式与普通函数注册不同。注意:请严格按照格式进行书写。看起来似乎很复杂,但是如果你用过array_walk,就会感觉到似曾相识了。
// average_step( ) is called on each row. function average_step(&$existing_data, $new_data) { $existing_data['total'] += $new_data; $existing_data['count']++; } // average_final( ) computes the average and returns it. function average_final(&$existing_data) { return $existing_data['total'] / $existing_data['count']; } //regist average , using average_step and average_final sqlite_create_aggregate($db, 'average', 'average_step', 'average_final'); $r = sqlite_query($db, 'SELECT average(number) FROM numbers'); 需要注意的是: SQLite对COUNT的语法支持与MySQL不同。
MySQL: select class, count(*) as cnt group by class where cnt > 3
SQLite: select class, count(*) as cnt group by class HAVING cnt >3
印象里面SQL2的规范方式就是这样的,只是MySQL为了方便更灵活处理了而已。
另外,对于自定义函数,还有一点需要说明:
如果数据是二进制(比如图象),需要进行解码和编码处理。因为函数是在SQLite内部运行的,二进制数据在SQLite内部是编码存储的。
$data = sqlite_udf_binary_decode($encoded_data);
.... .... //deal with $data $result = sqlite_udf_binary_encode($return_value); ~~呵呵~~ SQLite研究——拾遗补漏SQLite研究——拾遗补漏
有一个替换的方案:phpSQLiteAdmin 目前版本是0.2,只有不到100K。配置部署也非常简单,放到Web的目录里面就可以了。
下面是一些实例代码,最常用的几种方法。分别实现: 执行非查询SQL,返回全部查询,逐条返回查询。 echo "<hr>PDOæ�¹å¼�<hr>"; PDO模式下注意,官方资料new PDO('sqlite:xxx'); echo "<hr>SQLiteç±»<hr>"; echo "<hr>Zendç±»<hr>";
在这里我并没有使用API方式,具体使用API可以参照下表: MySQL mysqli_connect( ) mysqli_close( ) mysqli_query( ) mysqli_fetch_row( ) mysqli_fetch_assoc( ) mysqli_num_rows( ) mysqli_insert_id( ) mysqli_real_escape_string( )
~~呵呵~~ SQLite研究——性能优化SQLite研究——性能优化
主要通过pragma指令来实现。 比如: 空间释放、磁盘同步、Cache大小等。
PRAGMA auto_vacuum; 查询或设置数据库的auto-vacuum标记。 正常情况下,当提交一个从数据库中删除数据的事务时,数据库文件不改变大小。未使用的文件页被标记并在以后的添加操作中 再次使用。这种情况下使用VACUUM命令释放删除得到的空间。 当开启auto-vacuum,当提交一个从数据库中删除数据的事务时,数据库文件自动收缩, (VACUUM命令在auto-vacuum开启的数据库中不起作用)。数据库会在内部存储一些信息以便支持这一功能,这使得 数据库文件比不开启该选项时稍微大一些。 只有在数据库中未建任何表时才能改变auto-vacuum标记。试图在已有表的情况下修改不会导致报错。
PRAGMA cache_size; 查询或修改SQLite一次存储在内存中的数据库文件页数。每页使用约1.5K内存,缺省的缓存大小是2000. 若需要使用改变大量多行的UPDATE或DELETE命令,并且不介意SQLite使用更多的内存的话,可以增大缓存以提高性能。 当使用cache_size pragma改变缓存大小时,改变仅对当前对话有效,当数据库关闭重新打开时缓存大小恢复到缺省大小。 要想永久改变缓存大小,使用default_cache_size pragma.
PRAGMA case_sensitive_like; LIKE运算符的缺省行为是忽略latin1字符的大小写。因此在缺省情况下'a' LIKE 'A'的值为真。可以通过打开 case_sensitive_like pragma来改变这一缺省行为。当启用case_sensitive_like,'a' LIKE 'A'为假而 'a' LIKE 'a'依然为真。
PRAGMA count_changes; 查询或更改count-changes标记。正常情况下INSERT, UPDATE和DELETE语句不返回数据。 当开启count-changes,以上语句返回一行含一个整数值的数据——该语句插入,修改或删除的行数。 返回的行数不包括由触发器产生的插入,修改或删除等改变的行数。 PRAGMA page_size; 查询或设置page-size值。只有在未创建数据库时才能设置page-size。页面大小必须是2的整数倍且大于等于512小于等于8192。 上限可以通过在编译时修改宏定义SQLITE_MAX_PAGE_SIZE的值来改变。上限的上限是32768.
PRAGMA synchronous; 查询或更改"synchronous"标记的设定。第一种形式(查询)返回整数值。 当synchronous设置为FULL (2), SQLite数据库引擎在紧急时刻会暂停以确定数据已经写入磁盘。 这使系统崩溃或电源出问题时能确保数据库在重起后不会损坏。FULL synchronous很安全但很慢。 当synchronous设置为NORMAL, SQLite数据库引擎在大部分紧急时刻会暂停,但不像FULL模式下那么频繁。 NORMAL模式下有很小的几率(但不是不存在)发生电源故障导致数据库损坏的情况。但实际上,在这种情况 下很可能你的硬盘已经不能使用,或者发生了其他的不可恢复的硬件错误。 设置为synchronous OFF (0)时,SQLite在传递数据给系统以后直接继续而不暂停。若运行SQLite的应用程序崩溃, 数据不会损伤,但在系统崩溃或写入数据时意外断电的情况下数据库可能会损坏。另一方面,在synchronous OFF时 一些操作可能会快50倍甚至更多。 在SQLite 2中,缺省值为NORMAL.而在3中修改为FULL. 使用2,内存模式。 PRAGMA temp_store; 查询或更改"temp_store"参数的设置。当temp_store设置为DEFAULT (0),使用编译时的C预处理宏 TEMP_STORE来定义储存临时表和临时索引的位置。当设置为MEMORY (2)临时表和索引存放于内存中。 当设置为FILE (1)则存放于文件中。temp_store_directory pragma 可用于指定存放该文件的目录。当改变temp_store设置,所有已存在的临时表,索引,触发器及视图将被立即删除。
SQLite研究——结构与应用SQLite研究——结构与应用
外键约束(FOREIGN KEY constraints) 完整的触发器支持(Complete trigger support) 完整的 ALTER TABLE 支持(Complete ALTER TABLE support) 嵌套事务(Nested transactions) RIGHT 和 FULL OUTER JOIN(RIGHT and FULL OUTER JOIN) 可写视图(Writing to VIEWs) GRANT 和 REVOKE(GRANT and REVOKE)
建议多建索引。前文可以看出,建索引对SQLite的消耗并不大,但是效果是非常明显的。 SQLite的维护工具还不完全。看到一个有趣的例子,对表进行优化: 在数据量不大的情况下未偿不可。因为官方介绍“VACUUM 命令会清空“空闲列表”,把数据库尺寸缩到最小。注意, VACUUM 会耗费一些时间(在 Linux 系统下大约0.5秒/兆)并且要使用两倍于数据库文件大小的磁盘空间。”。用复制的方式可能会更快。 前面已经提到,SQLite是无数据类型存储的,但是还是建议不要在你的表里面使用无类型。同时,在程序侧对录入数据进行类型检查。 官方将之称为:type or column affinity 具体在应用中可能发生的是: 1,一个整型字段中,存进去一个字符串。 2,声明一个VARCHAR(10),SQLite一样可以让你存放500个字符在里面。 并且它们会始终完整无缺——决不会被截断。 那么设置类型还有什么用呢?A,索引;B,整理;C,防止你自己忘记。:) SQLite支持的数据结构: 1. Storage Classes NULL. The value is a NULL value. INTEGER. The value is a signed integer, stored in 1, 2, 3, 4, 6, or 8 bytes depending on the magnitude of the value. REAL. The value is a floating point value, stored as an 8-byte IEEE floating point number. TEXT. The value is a text string, stored using the database encoding (UTF-8, UTF-16BE or UTF-16-LE). BLOB. The value is a blob of data, stored exactly as it was input. 2. Column Affinity SQLite支持的语法: 最后: 如果你在Windows用,最好用filename.sqlite做文件名。或者,不用扩展名。
$db = sqlite_open($table) sqlite_close($db) $r = sqlite_query($db, $sql) $r = sqlite_query_array($db, $sql) $r = sqlite_query_unbuffered($db, $sql) sqlite_fetch_array($r) sqlite_fetch_single($r) $safe = sqlite_escape_string($s) $id = sqlite_last_insert_rowid($r)
SQLite研究——特性SQLite研究——特性
即使设置了列的类型为Integer,仍然可以将String值存放进去。 唯一的例外: 作为PrimaryKey的Integer。 另外,PrimaryKey的Integer还有一个特性,就是Insert时为null,会自动按照自增量存放。 在我的上一篇中的测试程序可以看到这一点。
Test 2: 25000 INSERTs in a transaction Test 3: 25000 INSERTs into an indexed table Test 4: 100 SELECTs without an index Test 5: 100 SELECTs on a string comparison Test 6: INNER JOIN without an index Test 7: Creating an index Test 8: 5000 SELECTs with an index * Performance of PostgreSQL in this test is most probably heavily impacted by psql command line utility. Same test when run form pgAdmin III GUI completed in 5 seconds. Test 10: 25000 UPDATEs with an index Test 11: 25000 text UPDATEs with an index Test 12: INSERTs from a SELECT Test 13: INNER JOIN with index on one side Test 14: INNER JOIN on text field with index on one side Test 15: 100 SELECTs with subqueries. Subquery is using an index Test 16: DELETE without an index Test 17: DELETE with an index Test 18: A big INSERT after a big DELETE Test 19: A big DELETE followed by many small INSERTs Test 20: DROP TABLE
以上数据引自SQLite.org。相信是很多PostgreSQL和MySQL的FANS感情上不能接受。 当然,这个测试有些偏向SQLite,但是从中也是可以分析得到很多有意事实的: 1,SQLite已经比以往版本有了长足进步。在轻量级数据情况下足以与常规DBM分庭抗礼。 2,在事务测试中表现优异,与其简单的文件存储方式有关。可以不用像MySQL那样对事务采取回避态度。 3,对Index的依赖度较高。尤其在Join操作上。 4,对字串的操作能力较差,尽量减少字符串比较。 5,DELETE消耗明显比UPDATE大。与其文件存储的结构有关。设计上可采用删除标志位方式。 测试外隐含的信息: 1,未测试并发性——推测:SQLlite对并发支持很差,尤其在重任务情况下。 2,无数据库中表的数量、存储数据的数量增加情况下的测试——不断的增加、删除数据,表数量也变得越来越多,这是一般应用中最常见的。推测:SQLite单一文件存储方式,对复杂结构的支持较弱。随着应用不断深入,性能会越来越差。 值得指出的是: 1,PostgreSQL虽然在各项测试中都表现不理想,但是在实际应用中表现并不差。因为它提供了很多优化工具,同时对锁和调度的处理非常优异,重负载情况下尤其突出。 2,MySQL的MyISAM与InnoDB的性能差异竟然到了如此小的程度?甚至很多项目中InnoDB都超越了MyISAM。我不是质疑测试结果,只是感慨。MyISAM的性能上确实已经很久没有什么改进了。在InnoDB上投入那么多,最后还是面临引擎断粮。MYSQL要解决的问题很多,不只是SELECT嵌套所暴露出来的那么简单。 综上所述,SQLite在如下方面具有优势: 1,独立产品,代码与数据库简单,封装后重复部署 2,数据量少,表结构简单 3,单次插入,多次读取,读取远高于插入 4,累增不删 5,表关联少 6,并发度低,对锁依赖低 在PHP应用中,有很多具有以上特征的产品。将代码与数据库一同打包,然后方便的进行部署或迁移,对提高开发效率、减少维护工作量具有重大意义。 ~~呵呵~~ SQLite研究——安装与环境SQLite研究——安装与环境
PHP已经内置了对SQLite的支持。 用如下代码可以测试当前PHP是否带有SQLite支持: 但是,仅有支持还是不够的。就像PhpMyAdmin极大的推动了MySQL在PHP下的应用一样,管理工具是非常重要的。比较推荐使用的是SQLiteManager。虽然官方声称在PHP4下也能正常工作,但是推荐使用PHP5,并且安装PDO。 Windows: 下载PHP5.1以上版本 编辑php.ini extension=php_pdo.dll 重启Apache。 下载:SQLiteManager (http://www.sqlitemanager.org/) 解压到htdocs/SQlite/ 编辑 ./include/user_defined.inc.php,调整这三个参数。 define("INCLUDE_LIB", 'e:/htdocs/SQLite/SQLiteManager/include/'); define ("SQLiteDb", 'e:htdocsSQLiteSQLiteManagerincludeconfig.db'); define("DEFAULT_DB_PATH", 'e:/htdocs/SQLite/'); 编辑: ./lang/simplified_chinese.inc.php Line21: 12=>"简体中文",13=>"繁体中文" 修改为: 13=>"简体中文",12=>"繁体中文" 是个BUG,作者将这两个搞反了。:) 然后可以运行一下了: http://localhost/SQLite/SQLiteManager/index.php 把test库删除,新建一个。看到如下视图说明OK了:
PHP预定义变量、常量PHP预定义变量、常量
供参考: PHP 的“魔术常量”
内核预定义常量 这些常量在 PHP 的内核中定义。它包含 PHP、Zend 引擎和 SAPI 模块。 PHP_VERSION (string) PHP_OS (string) DEFAULT_INCLUDE_PATH (string) PEAR_INSTALL_DIR (string) PEAR_EXTENSION_DIR (string) PHP_EXTENSION_DIR (string) PHP_BINDIR (string) PHP_LIBDIR (string) PHP_DATADIR (string) PHP_SYSCONFDIR (string) PHP_LOCALSTATEDIR (string) PHP_CONFIG_FILE_PATH (string) PHP_OUTPUT_HANDLER_START (integer) PHP_OUTPUT_HANDLER_CONT (integer) PHP_OUTPUT_HANDLER_END (integer) E_ERROR (integer) E_WARNING (integer) E_PARSE (integer) E_NOTICE (integer) E_CORE_ERROR (integer) E_CORE_WARNING (integer) E_COMPILE_ERROR (integer) E_COMPILE_WARNING (integer) E_USER_ERROR (integer) E_USER_WARNING (integer) E_USER_NOTICE (integer) E_ALL (integer) 标准预定义常量 这些常量是 PHP 默认定义的。 EXTR_OVERWRITE (integer) EXTR_SKIP (integer) EXTR_PREFIX_SAME (integer) EXTR_PREFIX_ALL (integer) EXTR_PREFIX_INVALID (integer) EXTR_PREFIX_IF_EXISTS (integer) EXTR_IF_EXISTS (integer) SORT_ASC (integer) SORT_DESC (integer) SORT_REGULAR (integer) SORT_NUMERIC (integer) SORT_STRING (integer) CASE_LOWER (integer) CASE_UPPER (integer) COUNT_NORMAL (integer) COUNT_RECURSIVE (integer) ASSERT_ACTIVE (integer) ASSERT_CALLBACK (integer) ASSERT_BAIL (integer) ASSERT_WARNING (integer) ASSERT_QUIET_EVAL (integer) CONNECTION_ABORTED (integer) CONNECTION_NORMAL (integer) CONNECTION_TIMEOUT (integer) INI_USER (integer) INI_PERDIR (integer) INI_SYSTEM (integer) INI_ALL (integer) M_E (float) M_LOG2E (float) M_LOG10E (float) M_LN2 (float) M_LN10 (float) M_PI (float) M_PI_2 (float) M_PI_4 (float) M_1_PI (float) M_2_PI (float) M_2_SQRTPI (float) M_SQRT2 (float) M_SQRT1_2 (float) CRYPT_SALT_LENGTH (integer) CRYPT_STD_DES (integer) CRYPT_EXT_DES (integer) CRYPT_MD5 (integer) CRYPT_BLOWFISH (integer) DIRECTORY_SEPARATOR (string) SEEK_SET (integer) SEEK_CUR (integer) SEEK_END (integer) LOCK_SH (integer) LOCK_EX (integer) LOCK_UN (integer) LOCK_NB (integer) HTML_SPECIALCHARS (integer) HTML_ENTITIES (integer) ENT_COMPAT (integer) ENT_QUOTES (integer) ENT_NOQUOTES (integer) INFO_GENERAL (integer) INFO_CREDITS (integer) INFO_CONFIGURATION (integer) INFO_MODULES (integer) INFO_ENVIRONMENT (integer) INFO_VARIABLES (integer) INFO_LICENSE (integer) INFO_ALL (integer) CREDITS_GROUP (integer) CREDITS_GENERAL (integer) CREDITS_SAPI (integer) CREDITS_MODULES (integer) CREDITS_DOCS (integer) CREDITS_FULLPAGE (integer) CREDITS_QA (integer) CREDITS_ALL (integer) STR_PAD_LEFT (integer) STR_PAD_RIGHT (integer) STR_PAD_BOTH (integer) PATHINFO_DIRNAME (integer) PATHINFO_BASENAME (integer) PATHINFO_EXTENSION (integer) CHAR_MAX (integer) LC_CTYPE (integer) LC_NUMERIC (integer) LC_TIME (integer) LC_COLLATE (integer) LC_MONETARY (integer) LC_ALL (integer) LC_MESSAGES (integer) ABDAY_1 (integer) ABDAY_2 (integer) ABDAY_3 (integer) ABDAY_4 (integer) ABDAY_5 (integer) ABDAY_6 (integer) ABDAY_7 (integer) DAY_1 (integer) DAY_2 (integer) DAY_3 (integer) DAY_4 (integer) DAY_5 (integer) DAY_6 (integer) DAY_7 (integer) ABMON_1 (integer) ABMON_2 (integer) ABMON_3 (integer) ABMON_4 (integer) ABMON_5 (integer) ABMON_6 (integer) ABMON_7 (integer) ABMON_8 (integer) ABMON_9 (integer) ABMON_10 (integer) ABMON_11 (integer) ABMON_12 (integer) MON_1 (integer) MON_2 (integer) MON_3 (integer) MON_4 (integer) MON_5 (integer) MON_6 (integer) MON_7 (integer) MON_8 (integer) MON_9 (integer) MON_10 (integer) MON_11 (integer) MON_12 (integer) AM_STR (integer) PM_STR (integer) D_T_FMT (integer) D_FMT (integer) T_FMT (integer) T_FMT_AMPM (integer) ERA (integer) ERA_YEAR (integer) ERA_D_T_FMT (integer) ERA_D_FMT (integer) ERA_T_FMT (integer) ALT_DIGITS (integer) INT_CURR_SYMBOL (integer) CURRENCY_SYMBOL (integer) CRNCYSTR (integer) MON_DECIMAL_POINT (integer) MON_THOUSANDS_SEP (integer) MON_GROUPING (integer) POSITIVE_SIGN (integer) NEGATIVE_SIGN (integer) INT_FRAC_DIGITS (integer) FRAC_DIGITS (integer) P_CS_PRECEDES (integer) P_SEP_BY_SPACE (integer) N_CS_PRECEDES (integer) N_SEP_BY_SPACE (integer) P_SIGN_POSN (integer) N_SIGN_POSN (integer) DECIMAL_POINT (integer) RADIXCHAR (integer) THOUSANDS_SEP (integer) THOUSEP (integer) GROUPING (integer) YESEXPR (integer) NOEXPR (integer) YESSTR (integer) NOSTR (integer) CODESET (integer) LOG_EMERG (integer) LOG_ALERT (integer) LOG_CRIT (integer) LOG_ERR (integer) LOG_WARNING (integer) LOG_NOTICE (integer) LOG_INFO (integer) LOG_DEBUG (integer) LOG_KERN (integer) LOG_USER (integer) LOG_MAIL (integer) LOG_DAEMON (integer) LOG_AUTH (integer) LOG_SYSLOG (integer) LOG_LPR (integer) LOG_NEWS (integer) LOG_UUCP (integer) LOG_CRON (integer) LOG_AUTHPRIV (integer) LOG_LOCAL0 (integer) LOG_LOCAL1 (integer) LOG_LOCAL2 (integer) LOG_LOCAL3 (integer) LOG_LOCAL4 (integer) LOG_LOCAL5 (integer) LOG_LOCAL6 (integer) LOG_LOCAL7 (integer) LOG_PID (integer) LOG_CONS (integer) LOG_ODELAY (integer) LOG_NDELAY (integer) LOG_NOWAIT (integer) LOG_PERROR (integer) 自 PHP 4.1.0 起,取得外部变量的首选方法是用下面提及的超全局变量。在此之前,人们要么依赖 register_globals,要么就是长长的预定义 PHP 数组($HTTP_*_VARS)。 在 PHP 5.0.0 中,长的 PHP 预定义数组可以通过设置 register_long_arrays 来屏蔽。 注: 在 PHP 4.1.0 及以后版本使用。之前的版本,使用 $HTTP_SERVER_VARS。 $_SERVER 是一个包含诸如头部(headers)、路径(paths)和脚本位置(script locations)的数组。数组的实体由 web 服务器创建。不能保证所有的服务器都能产生所有的信息;服务器可能忽略了一些信息,或者产生了一些未在下面列出的新的信息。这意味着,大量的这些变量在 CGI 1.1 specification 中说明,所以您应该仔细研究它。 这是一个“superglobal”,或者可以描述为自动全局变量。这只不过意味这它在所有的脚本中都有效。在函数或方法中您不需要使用 global $_SERVER; 访问它,就如同使用 $HTTP_SERVER_VARS 一样。 $HTTP_SERVER_VARS 包含着同样的信息,但是不是一个自动全局变量。(注意: $HTTP_SERVER_VARS 和 $_SERVER 是不同的变量,PHP 处理它们的方式不同。) 如果设置了 register_globals 指令,这些变量也在所有脚本中可用;也就是,分离了 $_SERVER 和 $HTTP_SERVER_VARS 数组。相关信息,请参阅安全的相关章节 使用 Register Globals。这些单独的全局变量不是自动全局变量。 您或许会发现下面列出的某些 $_SERVER 元素并不可用。注意,如果以命令行方式运行 PHP,下面列出的元素几乎没有有效的(或是没有任何实际意义的)。
当前正在执行脚本的文件名,与 document root相关。举例来说,在URL地址为 http://example.com/test.php/foo.bar 的脚本中使用 $_SERVER['PHP_SELF'] 将会得到 /test.php/foo.bar 这个结果。 如果 PHP 以命令行方式运行,该变量无效。 传递给该脚本的参数。当脚本运行在命令行方式时,argv 变量传递给程序 C 语言样式的命令行参数。当调用 GET 方法时,该变量包含请求的数据。 包含传递给程序的命令行参数的个数(如果运行在命令行模式)。 服务器使用的 CGI 规范的版本。例如,“CGI/1.1”。 当前运行脚本所在服务器主机的名称。如果该脚本运行在一个虚拟主机上,该名称是由那个虚拟主机所设置的值决定。 服务器标识的字串,在响应请求时的头部中给出。 请求页面时通信协议的名称和版本。例如,“HTTP/1.0”。 访问页面时的请求方法。例如:“GET”、“HEAD”,“POST”,“PUT”。 查询(query)的字符串。 当前运行脚本所在的文档根目录。在服务器配置文件中定义。 当前请求的 Accept: 头部的内容。 当前请求的 Accept-Charset: 头部的内容。例如:“iso-8859-1,*,utf-8”。 当前请求的 Accept-Encoding: 头部的内容。例如:“gzip”。 当前请求的 Accept-Language: 头部的内容。例如:“en”。 当前请求的 Connection: 头部的内容。例如:“Keep-Alive”。 当前请求的 Host: 头部的内容。 链接到当前页面的前一页面的 URL 地址。不是所有的用户代理(浏览器)都会设置这个变量,而且有的还可以手工修改 HTTP_REFERER。因此,这个变量不总是正确真实的。 当前请求的 User_Agent: 头部的内容。该字符串表明了访问该页面的用户代理的信息。一个典型的例子是:Mozilla/4.5 [en] (X11; U; Linux 2.2.9 i586)。您也可以使用 get_browser() 得到这个信息。 正在浏览当前页面用户的 IP 地址。 正在浏览当前页面用户的主机名。反向域名解析基于该用户的 REMOTE_ADDR。 注: 必须配置 Web 服务器来建立此变量。例如 Apache 需要在 httpd.conf 中有 HostnameLookups On。参见 gethostbyaddr()。 用户连接到服务器时所使用的端口。 当前执行脚本的绝对路径名。 该值指明了 Apache 服务器配置文件中的 SERVER_ADMIN 参数。如果脚本运行在一个虚拟主机上,则该值是那个虚拟主机的值。 服务器所使用的端口。默认为“80”。如果你使用 SSL 安全连接,则这个值为您所设置的 HTTP 端口。 包含服务器版本和虚拟主机名的字符串。 当前脚本所在文件系统(不是文档根目录)的基本路径。这是在服务器进行虚拟到真实路径的映像后的结果。 包含当前脚本的路径。这在页面需要指向自己时非常有用。 访问此页面所需的 URI。例如,“/index.html”。 当 PHP 运行在 Apache 模块方式下,并且正在使用 HTTP 认证功能,这个变量便是用户输入的用户名。 当 PHP 运行在 Apache 模块方式下,并且正在使用 HTTP 认证功能,这个变量便是用户输入的密码。 当 PHP 运行在 Apache 模块方式下,并且正在使用 HTTP 认证功能,这个变量便是认证的类型。 环境变量:$_ENV 注: 在 PHP 4.1.0 及以后版本使用。之前的版本,使用 $HTTP_ENV_VARS。 在解析器运行时,这些变量从环境变量转变为 PHP 全局变量名称空间(namespace)。它们中的许多都是由 PHP 所运行的系统决定。完整的列表是不可能的。请查看您系统的文档以确定其特定的环境变量。 其它环境变量(包括 CGI 变量),无论 PHP 是以服务器模块或是以 CGI 处理方式运行,都在这里列出了。 这是一个“superglobal”,或者可以描述为自动全局变量。这只不过意味这它在所有的脚本中都有效。在函数或方法中您不需要使用 global $_ENV; 来访问它,就如同使用 $HTTP_ENV_VARS 一样。 $HTTP_ENV_VARS 包含着同样的信息,但是不是一个自动全局变量。(注意: HTTP_ENV_VARS 和 $_ENV 是不同的变量,PHP 处理它们的方式不同。) 如果设置了 register_globals 指令,这些变量也在所有脚本中可用;也就是,分离了 $_ENV 和 $HTTP_ENV_VARS 数组。相关信息,请参阅安全的相关章节 使用 Register Globals。这些单独的全局变量不是自动全局变量。 注: 在 PHP 4.1.0 及以后版本使用。之前的版本,使用 $HTTP_COOKIE_VARS。 通过 HTTP cookies 传递的变量组成的数组。是自动全局变量。 这是一个“superglobal”,或者可以描述为自动全局变量。这只不过意味这它在所有的脚本中都有效。在函数或方法中您不需要使用 global $_COOKIE; 来访问它,就如同使用 $HTTP_COOKIE_VARS 一样。 $HTTP_COOKIE_VARS 包含着同样的信息,但是不是一个自动全局变量。(注意: HTTP_COOKIE_VARS 和 $_COOKIE 是不同的变量,PHP 处理它们的方式不同。) 如果设置了 register_globals 指令,这些变量也在所有脚本中可用;也就是,分离了 $_COOKIE 和 $HTTP_COOKIE_VARS 数组。相关信息,请参阅安全的相关章节 使用 Register Globals。这些单独的全局变量不是自动全局变量。 注: 在 PHP 4.1.0 及以后版本使用。之前的版本,使用 $HTTP_GET_VARS。 通过 HTTP GET 方法传递的变量组成的数组。是自动全局变量。 这是一个“superglobal”,或者可以描述为自动全局变量。这只不过意味这它在所有的脚本中都有效。在函数或方法中您不需要使用 global $_GET; 来访问它,就如同使用 $HTTP_GET_VARS 一样。 $HTTP_GET_VARS 包含着同样的信息,但是不是一个自动全局变量。(注意: HTTP_GET_VARS 和 $_GET 是不同的变量,PHP 处理它们的方式不同。) 如果设置了 register_globals 指令,这些变量也在所有脚本中可用;也就是,分离了 $_GET 和 $HTTP_GET_VARS 数组。相关信息,请参阅安全的相关章节 使用 Register Globals。这些单独的全局变量不是自动全局变量。 注: 在 PHP 4.1.0 及以后版本使用。之前的版本,使用 $HTTP_POST_VARS。 通过 HTTP POST 方法传递的变量组成的数组。是自动全局变量。 这是一个“superglobal”,或者可以描述为自动全局变量。这只不过意味这它在所有的脚本中都有效。在函数或方法中您不需要使用 global $_POST; 来访问它,就如同使用 $HTTP_POST_VARS 一样。 $HTTP_POST_VARS 包含着同样的信息,但是不是一个自动全局变量。(注意: HTTP_POST_VARS 和 $_POST 是不同的变量,PHP 处理它们的方式不同。) 如果设置了 register_globals 指令,这些变量也在所有脚本中可用;也就是,分离了 $_POST 和 $HTTP_POST_VARS 数组。相关信息,请参阅安全的相关章节 使用 Register Globals。这些单独的全局变量不是自动全局变量。 注: 在 PHP 4.1.0 及以后版本使用。之前的版本,使用 $HTTP_POST_FILES。 通过 HTTP POST 方法传递的已上传文件项目组成的数组。是自动全局变量。 这是一个“superglobal”,或者可以描述为自动全局变量。这只不过意味这它在所有的脚本中都有效。在函数或方法中您不需要使用 global $_FILES; 来访问它,就如同使用 $HTTP_POST_FILES 一样。 $HTTP_POST_FILES 包含着同样的信息,但是不是一个自动全局变量。 如果设置了 register_globals 指令,这些变量也在所有脚本中可用;也就是,分离了 $_FILES 和 $HTTP_POST_FILES 数组。相关信息,请参阅安全的相关章节 使用 Register Globals。这些单独的全局变量不是自动全局变量。 注: 在 PHP 4.1.0 及以后版本使用。之前的版本,没有等价的数组。 注: 在 PHP 4.3.0 之前,$_FILES 也被包括在 $_REQUEST 数组中。 此关联数组包含 $_GET,$_POST 和 $_COOKIE 中的全部内容。 这是一个“superglobal”,或者可以描述为自动全局变量。这只不过意味着它在所有的脚本中都有效。在函数或方法中您不需要使用 global $_REQUEST; 来访问它。 如果设置了 register_globals 指令,这些变量也在所有脚本中可用;也就是,分离了 $_REQUEST 数组。相关信息,请参阅安全的相关章节 使用 Register Globals。这些单独的全局变量不是自动全局变量。 注: 在 PHP 4.1.0 及以后版本使用。之前的版本,使用 $HTTP_SESSION_VARS。 包含当前脚本中 session 变量的数组。参阅 Session 函数 文档以获得更多信息。 这是一个“superglobal”,或者可以描述为自动全局变量。这只不过意味这它在所有的脚本中都有效。在函数或方法中您不需要使用 global $_SESSION; 来访问它,就如同使用 $HTTP_SESSION_VARS 一样。 $HTTP_SESSION_VARS 包含着同样的信息,但是不是一个自动全局变量。 如果设置了 register_globals 指令,这些变量也在所有脚本中可用;也就是,分离了 $_SESSION 和 $HTTP_SESSION_VARS 数组。相关信息,请参阅安全的相关章节 使用 Register Globals。这些单独的全局变量不是自动全局变量。 注: $GLOBALS 在 PHP 3.0.0 及以后版本中适用。 由所有已定义全局变量组成的数组。变量名就是该数组的索引。 这是一个“superglobal”,或者可以描述为自动全局变量。这只不过意味这它在所有的脚本中都有效。在函数或方法中您不需要使用 global $GLOBALS; 来访问它。 $php_errormsg 是包含 PHP 产生的上一错误消息内容的变量。该变量在发生错误并且track_errors 选项打开(默认为关闭)后才有效。 September 06 NCR编码:任意字符集下正常显示文字NCR编码:任意字符集下正常显示文字jimmy | 05 九月, 2006 22:16
NCR(Numeric character reference) 。 今天做xslt,意外留意到XSLTProcessor ->transformToDoc后输出的是NCR编码,觉得有必要提一下。其实就是把字符转Unicode,然后写成 &#x????; 其中,????是字符的十六进制。比如:泰拳 有两个特例: 1,ASC128以内的不用转。英文特权。 2,16进制的0xFEFF不用转。这个是Unicode开头的标志。判断一个文件的格式是不是Unicode的,用十六进制模式看开头的两个字节,是FEFF那就是了。 另外,意外的发现,NCR编码后字串,在Google中能够按解码后的进行搜索:) 编码的函数:
如果想得到别的语言的编码,可以改变页面的字符集然后提交,ICONV改成相应的编码。其实最常用的就是国家名或者语言名。这个在新版的PhpMyAdmin里面就有现成的:
~~呵呵~~ 将xml+xslt输出为HTML格式将xml+xslt输出为HTML格式jimmy | 05 九月, 2006 21:16
为兼容性考虑,有时候需要将XML转换为HTML格式输出。 PHP需要XSLT相关函数支持。PHP4和PHP5有较大的变化: PHP4: --enable-xslt --with-xslt-sablot PHP5: --width-xsl 安装PHP5系统需要 libxslt-devel, libgpg-error-devel, libgcrypt-devel 参考编译选项: ./configure --prefix=/usr/local/php5.1 --with-mysql=/usr/local/mysql --with-iconv --with-apxs2=/usr/local/apache2/bin/apxs --with-zlib --with-xsl 程序相对简单,
如果是直接处理变量,用 DomDocument->loadXML($string) 这里有一个需要注意的地方,根据PHP文档 XSLTProcessor->transFromToDoc的范例,里面使用: echo trim($proc->transformToDoc($xml)->firstChild->wholeText(); 这个用法是有问题的。因为firstChild可能为空,会给调试带来很多困惑。
一个有意思的附带结果是,输出内容被编码为NCR(Numeric character reference) 编码: 爱好泰拳的美国性感小猫 关于NCR编码,以后有时间会另文来介绍。
~~呵呵~~ 做缩略图的函数做缩略图的函数jimmy | 04 九月, 2006 14:47
改一个别组的产品,里面还在用PHPImage的函数,改成用ImageMagick的。 用的是以前写的lz_thumb基本代码。
<code>
</code> 如何用JS获取Cookie的domain和path?如何用JS获取Cookie的domain和path?jimmy | 01 九月, 2006 21:27
基于HTTP1.1协议,JS和PHP对Cookie的封装都很简易,基本上是拿来就用。 但是,在复杂应用中常常遇到这样的困惑: 为什么有的时候删除了Cookie但是值还存在?常常是因为Cookie的Domain和Path造成的。但是PHP和JS并没有提供直接的方法来判断读取到的cookie是属于哪个域名和路径。 这里提供一个思路。架设当前域名和路经是: domain3.dumain2.domain1.com/path1/path2 1,保存当前Cookie值。 2,setcookie(cookiename,'',-100,'/path1/path2','domain3.domain2.domain1.com'); 3,再次加载读取Cookie,如果Cookie存在,说明不是/path1/path2与domain3.domain2.domain1.com下的Cookie值。 4,尝试 /path1/path2 + domain2.domain1.com 以后依次尝试 /path1 , / , domain1.com ... 的不同组合,直至找到该Cookie。则当前的路径和域名就是该Cookie的路径和域名。 5,最后恢复原始cookie值。 另一个启示是,如果需要确切删除一个Cookie值时,将所有路径与域名的组合都进行一遍setcookie,才能确保Cookie被清除。
~~呵呵~~ Lucene- zend search- 笔记3Lucene- zend search- 笔记3jimmy | 24 八月, 2006 21:53
从Zend.com下载 ZendFramework-0.1.5.tar.gz ,解压。 实例:将数据库内容进行索引
E文搜索正确,中文不正常。 根据ZF的手册,Zend-search工作在UTF-8下。但是实测中,将数据进行了UTF-8编码后,仍然不能正常搜索中文。 留个疑问,有时间了来解决这个问题。Zend-search还在不断改进,应该后续版本对编码的兼容性有更好的解决。 ~~呵呵~~ Lucene- zend search- 笔记2Lucene- zend search- 笔记2jimmy | 23 八月, 2006 21:37
Lucene的安装: 从Sun.com下载 jdk-1_5_0_08-linux-i586-rpm.bin chmod +x jdk-1_5_0_08-linux-i586-rpm.bin ./jdk-1_5_0_08-linux-i586-rpm.bin Redhat默认的Java解释器为gcj: lrwxrwxrwx 1 root root 22 Jun 6 00:49 /usr/bin/java -> /etc/alternatives/java lrwxrwxrwx 1 root root 35 Jun 6 00:49 java -> /usr/lib/jvm/jre-1.4.2-gcj/bin/java 需要修改成新安装的JDK: cd /etc/alternatives mv java java.old ln -s /usr/java/jdk1.5.0_08/bin/java java 成为这个样子: lrwxrwxrwx 1 root root 30 Sep 4 10:47 java -> /usr/java/jdk1.5.0_08/bin/java 然后,从apache.org下载lucene: lucene-2.0.0.tar.gz 安装过程: tar -xzvf lucene-2.0.0.tar.gz mv lucene-2.0.0 /usr/local CLASSPATH=/usr/local/lucene-2.0.0/lucene-core-2.0.0.jar:/usr/local/lucene-2.0.0/lucene-demos-2.0.0.jar export CLASSPATH OK。然后可以测试了: java org.apache.lucene.demo.IndexFiles /usr/local/apache2/htdocs/ java org.apache.lucene.demo.SearchFiles 提示你输入一个检索的字串,输入后显示出结果。 安装OK。
~~呵呵~~ Lucene- zend search- 笔记1Lucene- zend search- 笔记1jimmy | 22 八月, 2006 15:34
常用的三种索引:
Keyword: 关键字,不分词的。比如,日期,ID Text:短文本。比如:标题,URL,Nickname UnStored:大文本,仅索引,不存储。比如:正文。
注意: 1,创建索引时, <code> $index = new Zend_Search_Lucene('/data/my-index', true); $index = new Zend_Search_Lucene('/data/my-index'); 第一个为新建,第二个为打开。 2, <code>$index->commit()</code> 的使用频率。控制在4M所有索引数据时进行一次提交比较合适。 令人感动的团队令人感动的团队jimmy | 14 八月, 2006 11:33
昨天是周日,下午来到公司看到的一幕令我非常感动。 安安静静的公司,走到社区的工位,却是热闹非凡,简直让人有种错觉:这是不是休息日?技术的同学在,运营的同学在,旅游的同学也在。因为十二层施工,旅游加班的同学下来借机器用,把社区挤的满满的,我都不得不另找其它位置坐。 大亮,唐唐,薛延超,橘子,小溪,宋扬,巍巍…… 这些都是加班的常客了。令我惊奇的是,晶晶也在。晶晶住的非常远,要公交地铁城铁才能到公司,路上要近两个小时。没有人要求,都是凭着对工作的责任心,凭着对社区团队的责任心,尽自己的努力去把工作做好。我没有说什么,但是感动一直在我心里。尤其是晶晶,如果我提前知道,一定不会让她这么远赶过来,哪怕是推后任务的期限,哪怕是我来替她分担些。 晚上回家的路上,我在回忆初来社区的时候。周六周日,社区的工位上只有指定值班的一个运营人员。而我们旁边,新闻频道,娱乐频道,都是有很多人。社区夹在中间,空空的静静的。而现在,整个11层,只有社区这里是热闹的,大家不是沉闷的而是充满活力的在工作着。 我并不是迷信加班文化,我感动是因为从中看到大家的责任心,看到大家的团队精神。强令别人加班,其实是很容易的事情,效果通常也不会太好。然而,当一个团队的成员能够积极主动的来做,而且愉快的来做的时候,那就是完全的不同了。 曾经走过很多艰苦的经历,曾经为这个团队付出过很多,在这一刻能够感觉到,一切都是值得。 我为在这样一个团队中而开心,也坚信这个团队会带给每个成员更多的自豪。 September 05 很久没有更新了,去了趟丽江JS中escape方法在PHP中的实现JS中escape方法在PHP中的实现jimmy | 27 七月, 2006 10:49
使用Ajax,用escape对字符进行编码是较为轻松的一种方式。 但是escape与PHP提供的url/utf编码,并不能很好对应,需要自己写一个函数来处理。 非常奇怪的是,很简单的一个函数,网上能找到很多,但是居然没有一个没有BUG的?换了两个版本后,觉得很失望,自己写吧。 参考了其他版本,在正则上进行了一些调整。 很多机器并没有装Iconv的,这个是个问题。或许有时间了会再写一个GB USC2之间的转码函数,就不用Iconv了。
~~呵呵~~ <code>
</code> JSON.PHP对中文乱码的解决JSON.PHP对中文乱码的解决jimmy | 27 七月, 2006 09:54
传递GB2312时候,发现有丢失内容情况,还会有乱码。 查看源代码,发现JSON试图将非ASCII字符转成UTF16格式,而处理过程中并未对GB有特殊处理,所以会导致错误。 分析了Json.js,在Script这一层上,Json并未对中文进行特殊编码处理。为何在PHP中要多此一举呢? 大概是为了跨平台传输的原因。 解决方法三个: 1,写一个GB2UTF16函数放进去。 2,采用其他编码作为中介。比如:nbase64 3,干脆不做处理。这个最简单。 根据需求,后台与前端均采用GB,UTF转码并无意义。动手改就很容易了。 decode函数中,找到:
将处理编码的地方全去掉: case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)): case (($ord_var_c & 0xE0) == 0xC0): case (($ord_var_c & 0xF0) == 0xE0): case (($ord_var_c & 0xF8) == 0xF0): case (($ord_var_c & 0xFC) == 0xF8): case (($ord_var_c & 0xFE) == 0xFC): 然后加上: default: 测试OK。 encode函数中也是一样,把编码的部分去掉,换上 default: $utf8 .= chr($ord_chrs_c);
~~呵呵~~ |
|
|