2010年2月6日

问题源自于深空博客的这篇文章《由会话重定向看到的对象销毁问题》,嗯,我以为这种问题早有人处理过了,因为2年前我就解决了此问题。解决办法已经发在phpchina.com的原创区:《关于PHP的Session处理的问题》。不过我在自己的博客上也发表同样的一篇帖子,留作备份。

 

在专家板块看到有人提出对Session处理机制的问题,原文《由会话重定向看到的对象销毁问题》。由于本人没有在专家板块发帖的资格,所以在这里发。

大概在08年年头我开始放弃Ruby on Rails转移到PHP开发,并以RoR的一些精神开发基于PHP的MVC框架,08年年底的时候,曾在phpchina这里发过一帖《自写MVC框架 Agi PHPMVC(核心)》,可以这么说,从我接触PHP以来一直是以自写的MVC框架在进行开发。目前该框架取名Agi on Rails,已经进入正式版的1.2版,下一个release版本将会考虑开源。该框架已经成功稳定的运行在多个Server Env(Windows、Linux,IIS、Apache、Lighttpd、Nginx),开发过超过20个项目,承受过一天超过1200万PV的洗礼(预计并发峰值在200左右)。为何加这一个插曲,是为了强调,我是坚持将数据操作写在Model层的,而Session处理的逻辑,是被设计成一个 Model,而随着众多Model被Controler和View层调用。而开发者,是可以针对Session这个模块进行后期的高级的逻辑封装的。

废话就不多说了,解决方案如下: 

 

1 // 数据库连接的抽象层
2  abstract class DB_Connector {
3
4 protected static
5 $_register = array();
6
7 static public function connect($anyKey) {
8 // 假设传入的$anyKey指定要使用MySQL进行连接
9 // 这中间的一些判断这里就忽略了
10   if (!isset(self::$_register[$anyKey])) {
11 self::$_register[$anyKey] = new DB_Connector_MySQL();
12 }
13 return self::$_register[$anyKey];
14 }
15
16 static public function disconnect($anyKey) {
17 self::connect($anyKey)->disconnect();
18 }
19
20 static public function handleDisconnect($anyKey) {
21 self::connect($anyKey)->handleDisconnect();
22 }
23 }
24
25  // 数据库连接的驱动层
26  class DB_Connector_MySQL {
27
28 protected
29 $_connector = null,
30 $_isHandleDisconnect = false;
31
32 public function __construct() {
33 // 执行具体的连接
34   $this->_connector = new MySQLDriver();
35 }
36
37 public function __destruct() {
38 if (!$this->_isHandleDisconnect)
39 $this->disconnect();
40 }
41
42 public function disconnect() {
43 $this->_connector = null;
44 }
45
46 public function handleDisconnect() {
47 $this->_isHandleDisconnect = true;
48 }
49 }
50
51  // Session的实现层
52 // Any_ActiveRecord是Model的抽象层,这里就不实现了
53  class Session extends Any_ActiveRecord {
54
55 protected static
56 $_connectorKey = 'Any';
57
58 // 标准实现
59 static public function open() {
60 // 一旦将Session处理转移给DB层面去控制
61 // 就意味着数据库连接的释放,也必须转交给这个Session模块来处理
62 DB_Connector::handleDisconnect(self::$_connectorKey);
63 // 其他启动配置,包括Session GC清理的基数等等
64 }
65
66 // 标准实现
67 //
68 static public function pick($sId) {
69
70 }
71
72 // 标准实现
73 static public function dump($sId, $val) {
74
75 }
76
77 // 标准实现
78 static public function destroy($sId) {
79
80 }
81
82 // 标准实现
83 static public function gc() {
84
85 }
86
87 // 标准实现
88 static public function close() {
89 // 一切OK,再由Session Close的时候,释放数据库连接
90 DB_Connector::disconnect(self::$_connectorKey);
91 }
92 }

至此,第一个问题解决了,就是关于数据库连接的释放问题。但是这里存在第二个问题(假如你在使用的框架,取出的Session是一个数组,或者你直接就取出的是一个数组,可以忽略第二个问题),就是按照常理,一个Session经由Model取出,理应被是一个Session的实例,然后,由于PHP本身的运行机制的问题,变量的释放,往往早于Session的注销。这时就要发挥出OO的本色了:

 

根据上述的Session类,我们进行一点点改造:

 

1 // Session的实现层
2 // Any_ActiveRecord是Model的抽象层,这里就不实现了
3 class Session extends Any_ActiveRecord {
4
5 protected static
6 $_connectorKey = 'Any',
7 $_currSess = null;
8
9 // 标准实现
10 static public function open() {
11 // 一旦将Session处理转移给DB层面去控制
12 // 就意味着数据库连接的释放,也必须转交给这个Session模块来处理
13 DB_Connector::handleDisconnect(self::$_connectorKey);
14 // 其他启动配置,包括Session GC清理的基数等等
15 }
16
17 // 标准实现
18 // 拿出Session
19 static public function pick($sId) {
20 self::$_currSess = self::find_by_sess_id($sId);
21 if (!self::$_currSess->isEmpty())
22 return self::$_currSess->value;
23 return false;
24 }
25
26 // 标准实现
27 static public function dump($sId, $val) {
28 // 新访客
29 if (self::$_currSess->isEmpty())
30 self::$_currSess->sess_id == $sId;
31 self::$_currSess->value = $val;
32 self::$_currSess->save();
33 }
34
35 // 标准实现
36 static public function destroy($sId) {
37
38 }
39
40 // 标准实现
41 static public function gc() {
42
43 }
44
45 // 标准实现
46 static public function close() {
47 // 一切OK,再由Session Close的时候,释放数据库连接
48 DB_Connector::disconnect(self::$_connectorKey);
49 self::$_currSess = null;
50 }
51 }

好了,大功告成!原理就不多说了,多做点测试吧。

 

将Session写成Model的好处是,可以有针对性的进行单元测试。也许有用户会担心,你把Session放在数据库层,能承受得多大的并发量呢?

OK,我可以给出一些实际数据,一个投票的程序,PHP和MySQL跑在同一台服务器(Server系统是Ubuntu Server以Lighttpd,已经通过压力测试优化过fastcgi线程数字)上,3天收集有效投票记录总数900万+(注意,有效投票是指限制ip的,每一票都要检查ip和该ip上一次投票的时间),Session使用Model操作,以MyISAM引擎存放在MySQL的表中,Session主键已经刷到8位数。最高峰一天PV 1200万。

 

另:我发现cnblogs的源代码极其以及十分之丑陋,无法让人家复制代码,提供附件下载

posted @ 2010-02-06 02:35 Janpoem 阅读(10) | 评论 (0)编辑

2009年12月29日

Eclipse 3.5汉化包,这是官方的汉化包,但是分40个包下载,而且Eclipse的汉化包下载也改了,没法用软件一次性下载了,每次都要点40*3=120次连接,疯了,打个包。。。。

 

点击下载

posted @ 2009-12-29 19:55 Janpoem 阅读(132) | 评论 (0)编辑

2009年12月12日

原文:http://www.garfieldtech.com/blog/magic-benchmarks

The day is nearly upon us! Drupal 7 will open up developers to PHP 5 functionality when it is released next year. Already, there is talk of how, and if, to leverage PHP 5's object handling now that we don't need to deal with the weirdness of PHP 4's object model. Of course, because it's Drupal, our army of performance czars want to know just what the cost is for object handling, and especially advanced object magic like __get(), __call(), the ArrayAccess interface, and so forth.

So let's find out. :-)

Benchmarking methodology

The exact numbers in the following tests aren't particularly interesting. What's interesting is their relative value. All tests are run in a single script (available at the bottom of this post) on the following system:

Lenovo Thinkpad T61 on AC power
Intel Core2 Duo 2.2 GHz
2 GB RAM
Kubuntu 7.10 "Gutsy"
PHP 5.2.3

Because it's a fairly beefy system, all tests are run 2,000,000 times so that we have worthwile numbers to compare. All times listed below are in seconds. Of course, any such tests will vary a bit between runs, and even between two tests in the same script. We're looking for overall trends here, not exact numbers, but it's important to keep in mind that micro-benchmarks are an inexact science. Also keep in mind that I don't know the internals of the PHP engine well at all, so my analysis is based on logical extrapolation, not actual knowledge of the PHP engine itself.

All tests use the following benchmarking mechanism:

<?php
error_reporting
(E_ALL | E_STRICT);
define('ITERATIONS', 2000000);
...
$start = microtime(true);
for (
$i=0; $i < ITERATIONS; ++$i) {
 
// something here we're testing.
}
$stop = microtime(true);
echo
"Test name: " . ($stop - $start) . " seconds". PHP_EOL;
?>

Functions

For completeness, we'll test ordinary functions, too. First define a dummy function that we can call:

<?php
function foo($a) {
  return;
}
?>

And we'll call it 4 different ways:

<?php
foo
(1); $foo = 'foo';
$foo(1); call_user_func('foo', 1); call_user_func_array('foo', array(1));
?>

Results:

Literal function    1.218
Variable function 1.305
call_user_func() 2.734
call_user_func_array() 3.386

As others have noted before, call_user_func*() is extremely slow. Unfortunately, it's also the main way to do function-level polymorphism in PHP.

Methods

Moving on the object oriented-code, our main interest here, let's look at three different ways of calling methods: Directly, via __call(), and via __call() with a generic pass-through using call_user_func_array():

<?php
class TestCall {
  function
normal() { return; }
  function
__call($method, $args) { return; }
}
$t = new TestCall(); // ... class TestCallSub {
  function
normal() { return; }
  function
bar() { return; }
  function
__call($method, $args) {
    if (
$method == 'foo') {
      return
call_user_func_array(array($this, 'bar'), $args);
    }
    return;
  }
}
$s = new TestCallSub(); // Normal method
$t->normal(); // __call() overhead
$t->doesntExist(); // __call() overhead with generic dispatch
$s->foo();
?>

Results:

Native Method                1.095
Magic Method (__call()) 3.018
Magic Method (with sub-function) 7.226

It looks like __call() is indeed not a speed deamon, but not as slow as I previously thought. Rather, it is call_user_func_array() that was the real killer. Between the two of them, call_user_func_array() has more overhead than __call() does. Mixing them is a performance nightmare.

Properties

PHP 5 also includes some magic overrides for properties: __get() and __set(). Let's see how expensive those are.

<?php
class TestGetSet {
  public
$foo = 1;
  public function
__get($var) {
    return
$this->foo;
  }
  public function
__set($var, $val) {
   
$this->foo = $val;
  }
}
$t = new TestGetSet(); $t->foo;
$t->bar;
$t->foo = 1;
$t->bar = 1;
?>

Results:

Get Native Property        0.619
Get Magic Property (__get()) 2.066
Set Native Property 0.752
Set Magic Property (__set()) 2.623

Again, magic is expensive. Curiously, both __get() and __set() are just over 3x the cost of the native equivalent (3.3x and 3.4x, respectively) while __call() is only 2.7x the cost.

Arrays

Another nifty feature of PHP 5 is the ArrayAccess interface, part of the Standard PHP Library. What does that cost us?

<?php
class TestArrayAccess implements ArrayAccess {
  private
$properties = array();
  public
$foo = 1;
  function
__construct($array) {
   
$this->properties = $array;
  }
  function
offsetExists($offset) {
    return isset(
$this->properties[$offset]);
  }
  function
offsetGet($offset) {
    return
$this->properties[$offset];
  }
  function
offsetSet($offset, $value) {
   
$this->properties[$offset] = $value;
  }
  function
offsetUnset($offset) {
    unset(
$this->properties[$offset]);
  }
}
$a = array('a' => 'A', 'b' => 'B', 'c' => 'C', 'd' => 'D');
$t = new TestArrayAccess($a); // Get array property
$a['b'];
// Set array property
$a['b'] = 'B';
// Get object property
$t->foo;
// Set object property
$t->foo = 1;
// Get ArrayAccess property
$t['b'];
// Set ArrayAccess property
$t['b'] = 'B';
?>

Results:

Get Array Property        0.473
Set Array Property 0.655
Get Object Property 0.598
Set Object Property 0.733
Get ArrayAccess Property 2.379
Set ArrayAccess Property 3.030

So we can determine 3 things here. One, setting a variable is a bit more expensive than reading it, but not enormously so. That's not surprising. Two, arrays are very slightly faster than objects for just reading a public property directly, but again not by much and probably not enough to worry about (especially when there are plenty of more expensive operations, as we are finding). Three, the ArrayAccess interface eats your CPU.

At first that seems surprising, but consider that each array access must first detect that it's using the extra language magic, then call a method, and in our case that method is not just trivially returning as it did in the earlier tests. It's doing an array lookup and returning an actual value. Still, a 4.6x-5x increase in time feels high. It's even a bit more expensive than __get() and __set().

Inheritance

What about simple inheritance? There are many ways to do polymorphism. So far we've determined that call_user_func_array() is a really lousy one from a performance perspective, and a wrapping function is going to cost an extra function call each time. What if we use inheritance for more traditional, "classic" polymorphism? Let's have a go.

<?php
class Base {
  public
$test = 1;
  public function
baseMethod() { return; }
  public function
overrideMe() { return; }
}
class
Child extends Base {
  public
$child = 1;
  public function
childMethod() { return; }
  public function
overrideMe() { return; }
}
$b = new Base();
$c = new Child(); $b->test;
$c->test;
$c->child;
$b->baseMethod();
$c->baseMethod();
$c->childMethod();
$c->overrideMe();
?>

Results:

Get Base Property        0.617
Get Base Property from Child 0.611
Get Child Property 0.625
Get Base Method 1.185
Get Base Method from Child 1.142
Get Child Method 1.141
Override Child Method 1.124

Finally, some good news! Not really surprising news, either. When all is said and done, inheritance is basically free as far as CPU cycles go. That should not come as a surprise. Properties and methods of an object are inherited at creation time, not call time, so once the object is created it doesn't really matter how it was created. At least from a performance perspective, then, inheritance is not a concern.

Composition

Of course, the blogosphere has been hopping recently about how inheritance is evil and inflexible and composition is so much better and more flexible. The catch, though, is that composition does incur a run-time cost in terms of extra method calls. Let's see what that cost is.

<?php
class Used {
  public function
myMethod() { return; }
}
class
User {
  protected
$used;
  public function
__construct() {
   
$this->used = new Used();
  }
  public function
myMethod() { return $this->used->myMethod(); }
}
$u = new User(); $u->myMethod();
?>

Results:

Get Composed Method    2.232

Wrapping a method via composition roughly doubles the performance cost, which is exactly what we'd expect from adding one more method call to the stack. No surprises here, either. Consider that the cost of composition. At least it's cheaper than call_user_func_array(). :-)

Iterators

The last test we'll make involves iterators. SPL includes a huge collection of iterators, but we're only going to look at two of them. We'll compare iterating over a native array with an object that uses an internal iterator, using the Iterator interface, and one using an external Iterator via IteratorAggregate and ArrayIterator.

<?php
class Internal implements Iterator {
  protected
$a;
  public function
__construct(array $a) {
   
$this->a = $a;
  }
  public function
current() {
    return
current($this->a);
  }
  public function
key() {
    return
key($this->a);
  }
  public function
next() {
    return
next($this->a);
  }
  public function
rewind() {
    return
reset($this->a);
  }
  public function
valid() {
    return (
current($this->a) !== FALSE);
  }
}
class
External implements IteratorAggregate {
  protected
$a;
  public function
__construct(array $a) {
   
$this->a = $a;
  }
  public function
getIterator() {
    return new
ArrayIterator($this->a);
  }
}
$a = array('A', 'B', 'C', 'D');
$internal = new Internal($a);
$external = new External($a);

foreach (

$a as $item);
foreach (
$internal as $item);
foreach (
$external as $item);
?>

Results:

Iterate array            1.67
Iterate internal iterator 22.87
Iterate external iterator 6.06

Oh dear god make it stop! A trivially-simple internal iterator has a performance hit of more than an order of magnitude over a native array. An external iterator is cheaper, but still not cheap.

Let's consider why that is, though. Using the Iterator interface, we're forcing PHP to call into user-space 2-3 times per iteration. (I'm not sure of the exact internals, but at minimum it would need to call next() and valid() each iteration, plus key() if we're requesting it.) That's three method calls per iteration, not counting the behind-the-scenes engine code to make the magic work. Maybe it's not so surprising then. The external iterator is faster here because we're using the ArrayIterator object, provided by SPL and implemented entirely in C. If we used a user-space external iterator, I would expect results similar to those for the internal iterator.

The moral of the story here is, as always, C is faster than PHP. The more you can do in C, the faster your code will be. (Hey, that rhymes!) If possible, use IteratorAggregate and ArrayIterator over an internal iterator. If that's not possible for some reason, say you're iterating over some external resource like a file handle or database result set, be aware that it's going to cost you.

Summary

So what have we learned? We've learned that there is no such thing as a free lunch, unless you're getting it from your parents. (Amazing how programming parallels real life, isn't it?) All of PHP 5's advanced object-oriented features have a cost, and sometimes that cost is non-trivial.

Does that mean we should avoid using them? Of course not! Magic methods, iterators, ArrayAccess, and the like make solving certain types of problems far easier and faster for the programmer. In many cases, throwing more CPU at the code is cheaper than writing more, clunkier, harder-to-maintain code. And if the advanced features are not used in critical sections of the program, you may not even notice the difference. These benchmarks should be used as guidelines only; moving your database server from the same computer to a dedicated database box will likely yield a bigger performance boost than expunging all traces of __get() from your code, and will almost certainly cost far less to do.

There's one other important observation that we haven't really mentioned. One of the big complaints about PHP 4's object model was that it was dog slow compared to procedural code. Well, whatever the truth to that it is no longer the case. Calling a function and calling a method is virtually identical in cost, at least under modern versions of PHP. Polymorphic code can eve be faster if using inheritance over composition or function-level composition (or god-forbid call_user_func_array()), although as always beware the inheritance trap. As with anything else, use wisely.

The raw data is available below, as is a graph of the results courtesy of OpenOffice.org Calc. I've left the internal iterator out of the graph as it would visually throw everything else off. The complete benchmark script used is available below as well.

Results (2 million iterations)
Operation Seconds
Literal function 1.218
Variable function 1.305
call_user_func() 2.734
call_user_func_array() 3.386
Native Method 1.095
Magic Method (__call()) 3.018
Magic Method (with sub-function) 7.226
Get Native Property 0.619
Get Magic Property (__get()) 2.066
Set Native Property 0.752
Set Magic Property (__set()) 2.623
Get Array Property 0.473
Set Array Property 0.655
Get Object Property 0.598
Set Object Property 0.733
Get ArrayAccess Property 2.379
Set ArrayAccess Property 3.030
Get Base Property 0.617
Get Base Property from Child 0.611
Get Child Property 0.625
Get Base Method 1.185
Get Base Method from Child 1.142
Get Child Method 1.141
Override Child Method 1.124
Get Composed Method 2.232
Iterate array 1.67
Iterate internal iterator 22.87
Iterate external iterator 6.06

Benchmarks

http://www.garfieldtech.com/blog/magic-benchmarkshttp://www.garfieldtech.com/blog/magic-benchmarks
posted @ 2009-12-12 16:35 Janpoem 阅读(9) | 评论 (0)编辑

原文:http://www.qianduan.net/rediscovering-html-tables.html

根 据我最近的一些实践以及在和一些读者进行关于HTML表格的使用问题沟通之后,决定写这篇文章。总的来说,我注意到由于误导性信息,他们对于 table的使用有种先入为主的厌恶。事实上很多人会说”我看到永远不应该使用表格”的说法,但是这绝对是错误的!这个建议只是针对使用HTML表格来定 义网页的布局,但是表格在方便的排列数据信息行和列方面非常完美,而且如果你一定要在一个页面上显示表列数据,你就不得不使用它们!为什么不呢?然而,在 这种情况下,一些人无视了用于table的某些HTML标签的存在并且不知道该如何正确的使用它们。\

HTML有10个表格相关标签。下面是一个带有简介的列表,但是首先,文档要被正确的定义在HTML 4.01/XHTML 1或HTML 5下面:

  • <caption> 定义表格标题(4, 5)
  • <col> 为表格的列定义属性(4, 5)
  • <colgroup> 定义表格列的分组(4, 5)
  • <table> 定义表格(4, 5)
  • <tbody> 定义表格主体(4, 5) \
  • <td> 定义一个单元格 (4, 5)
  • <tfoot> 定义表格的表注(底部)(4, 5)
  • <th> 定义表格的表头 (4, 5)
  • <thead> 定义表格的表头(4, 5)
  • <tr> 定义表格的行(4, 5)

一个基本的表格结构如下:

它包含一个标题、头部、主体和底部。正确的HTML元素顺序是:

  1. <table>
  2. <caption>
  3. <thead>
  4. <tfoot>
  5. <tbody>

你也可以使用<col> 和<colgroup> 来定义表格的列或为列分组:

  1. <table>
  2. <caption>
  3. <colgroup>
  4. <col>
  5. <thead>
  6. <tfoot>
  7. <tbody>

下面是一个正确的表格结构实例:

<table border="1">
 <caption>Table caption here</caption>
 <colgroup span="1" style="background:#DEDEDE;"/>
 <colgroup span="2" style="background:#EFEFEF;"/>
 
 <!-- Table Header-->
 <thead>
 <tr>
  <th>Head 1</th>
   <th>Head 2</th>
   <th>Head 3</th>
  </tr>
 </thead>
 
 <!-- Table Footer-->
 <tfoot>
  <tr>
   <td>Foot 1</td>
   <td>Foot 2</td>
   <td>Foot 3</td>
  </tr>
 </tfoot>
 
 <!-- Table Body-->
 <tbody>
  <tr>
   <td>A</td>
   <td>B</td>
   <td>C</td>
  </tr>
  <tr>
   <td>D</td>
   <td>E</td>
   <td>F</td>
  </tr>
 </tbody>
</table>

在浏览器中的结果如下图所示:

关于表格的一些技巧

  • 根据w3schools的解释和用法,在一个table定义中,<tfoot>元素必须出现在<tbody>之前,这样,浏览器就可以在接受到所有数据之前呈现表注了。另外,如果不是这个顺序,将不能通过W3C的HTML4和XHTML验证,无论你声明哪种DTD。(了解更多)。
  • 在 HTML 4.01 中,表格的align和bgcolor属性不赞成使用,所以在HTML 5中不再有任何table的属性被支持(事实上,在XHTML 1.0 Strict DTD中已经不支持”align”和”bgcolor”属性了);
  • 所有主流浏览器都支持<colgroup> 标签,但是Firefox、Chrome 以及 Safari 仅支持 colgroup 元素的 span 和 width 属性;
  • css中的empty-cells:show|hide 可以设定空单元格是否显示边框。注意,这个需要设置在table而不是td/th中。IE6中比较容易遇到该问题;
  • css中的border-collapse:collapse | separate 可以设置表格的边框是否被合并成一个边框;
  • css中的border-spacing属性等效于table的cellspacing属性。
    为了实现现在所提倡的表现和结构分离的开发模式,前端观察建议将页面中所有与表现层有关的东东,都用CSS来控制,不用HTML自带的属性来控制页面的表现,而table是最容易被忽略的一个。

关于table的更多详细内容可以查看W3C的文档: w3 Introduction to tables

最后留一个非常简单的问题给大家,CSS的哪个属性等效于table的cellpadding属性?

posted @ 2009-12-12 16:32 Janpoem 阅读(7) | 评论 (0)编辑

2009年12月11日

原文作者:IIduce

原文地址:http://css9.net/css-font-face-solution/

作者博客:http://css9.net/


字体使用是网页设计中不可或缺的一部分。经常地,我们希望在网页中使用某一特定字体,但是该字体并非主流操作系统的内置字体,这样用户在浏览页面的时候就有可能看不到真实的设计。美工设计师最常做的办法是把想要的文字做成图片,这样做有几个明显缺陷:1. 不可能大范围的使用该字体;2. 图片内容相对使用文字不易修改;3. 不利于网站SEO(主流搜索引擎不会将图片alt内容作为判断网页内容相关性的有效因素)。网络上有一些使用sIFR技术、或javascript/flash hack的方法,但实现起来或繁琐,或有缺陷。下面要讲的是如何只通过CSS的@font-face属性来实现在网页中嵌入任意字体。

 

【第一步】

 

获取要使用字体的三种文件格式,确保能在主流浏览器中都能正常显示该字体。

  • .TTF或.OTF,适用于Firefox 3.5、Safari、Opera
  • .EOT,适用于Internet Explorer 4.0+
  • .SVG,适用于Chrome、IPhone

下面要解决的是如何获取到某种字体的这三种格式文件。一般地,我们在手头上(或在设计资源站点已经找到)有该字体的某种格式文件,最常见的是.TTF文件,我们需要通过这种文件格式转换为其余两种文件格式。字体文件格式的转换可以通过网站FontsQuirrelonlinefontconverter提供的在线字体转换服务获取。这里推荐第一个站点,它允许我们选择需要的字符生成字体文件(在服务的最后一个选项),这样就大大缩减了字体文件的大小,使得本方案更具实用性。

 

【第二步】

 

获取到三种格式的字体文件后,下一步要在样式表中声明该字体,并在需要的地方使用该字体。

字体声明如下:

 

 

 1 @font-face {
 2     font-family: 'fontNameRegular';
 3     src: url('fontName.eot');
 4     src: local('fontName Regular'), 
 5          local('fontName'), 
 6          url('fontName.woff') format('woff'), 
 7          url('fontName.ttf') format('truetype'), 
 8          url('fontName.svg#fontName') format('svg');
 9 }  
10 /*其中fontName替换为你的字体名称*/


在页面中需要的地方使用该字体:

1 p  { font: 13px fontNameRegular, Arial, sans-serif; }
2 h1 {font-family: fontNameRegular}


或者

 

1 <p style="font-family: fontNameRegular">掬水月在手,落花香满衣</p>


示例就不转载了,欢迎去作者的原文看看效果。

 

posted @ 2009-12-11 09:03 Janpoem 阅读(4) | 评论 (0)编辑

2009年11月17日

国外著名网站smashingmagazine给大家带来了50款优秀而又实用的PHP工具,其中包括PHP代码测试、优化工具,图像处理工具,以及开发过程必须的软件配置管理工具等,相信这些工具能够让使用PHP的朋友如虎添翼! 50款优秀而又实用的PHP工具:
一、PHP代码调试工具 Webgrind Webgrind完美支持PHP 5,安装迅速简便,可以跨越多个平台运行。 Xdebug Xdebug是使用极为广泛的PHP代码调试工具,它提供大量的工具帮助你找出程序中潜在的BUG,并且它得到了很多PHP开发工具的支持,以做为专门的测试工具继承在这些开发工具中,比如PHPEclipse、phpDesigner等。 Gubed PHP Debugger DBG PHP_Debug PHP_Debug是一款开源的 PHP代码调试工具,它能够从多方面给出有用的信息从而帮助你排除代码中存在的问题,并且集成性能测试工具,比如PHP代码执行时间以及SQL语句执行时间等信息。 PHP_Dyn MacGDBp

二、PHP代码测试、优化工具 PHPUnit :一款基于PHP 5的JUnit组件测试工具。 SimpleTest SimpleTest是一款高度集成的PHP代码测试工具。 Selenium :一款专业全自动WEB站点PHP代码测试工具,比较侧重的UI输入输出数据测试。 PHP_CodeSniffer dBug 一款专注于测试类、对象、数组以及XML文件的PHP工具。 PHP Profile Class

三、文档管理工具 phpDocumentor :一款著名的PHP代码管理工具,支持PHP源代码到HTML、 PDF、CHM等格式的文档输出。 PHP DOX

四、安全类工具 Securimage :好用的图像格式验证码工具。 Scavenger :一款实时攻击检测工具。 PHP-IDS :一款非法潜入检测工具。 Pixy :一款危险代码检查工具,检测来自编程人员自身或者外部信息提交可能的破坏性代码。 

五、图形图像处理工具 PHP/SWF Charts pChart - a chart-drawing PHP library WideImage MagickWand For PHP 

六、PHP代码格式处理工具这些工具可以帮助你按照需求对源代码进行相应的格式处理,比如代码缩进以及分段等,是代码看上去结构分明,易于复用及管理。 PHP_Beautifier PHPCodeBeautifier GeSHi - Generic Syntax Highlighter

七、配置管理工具(版本控制)软件配置管理中有一个比较重要的环节-代码版本库的维护,这样有利于同版本的交叉开发、维护以及后期版本回溯,这对于大型项目尤为重要,以下两款工具可以很好的帮助你。 Phing xinc

八、PHP扩展、工具集、类库支持 SimplePie 此工具可用于PHP RSS解析。 HTML Purifier :此工具可以用来移除所有恶意代码(XSS),而且还能确保你的页面遵循W3C的标准规范。 TCPDF :一个可以用于快速生成PDF文件的PHP5函数包。 htmlSQL :一组可以使你方便的对HTML和XML内容方便的使用类似SQL语句进行检索的PHP类集。 The Greatest PHP Snippet File Ever (Using Quicktext for Notepad++) Creole :本工具使用PHP 5编写, 是一款真正意义的OO的层,包含丰富的以JDBC为基础的 API接口。 PHPLinq :帮助你方便的使用SQL语法对PHP数组进行操作,避免不正当的数组初始化以及溢出 PHPMathPublisher 本工具可以帮助你方便的使用脚本语言创建类似上图的复杂数学表达式。 phpMyAdmin :大家很熟悉的一款SQL管理工具,提供完善的GUI环境帮助你操作MySQL。 PHPExcel :一组MS Office Excel 文档生成类库。 Phormer :轻量级PHP相册。 xajax PHP Class Library :开源PHP类库,帮助你轻松实现多种ajax效果。 PHP User Class :PHP用户管理类库支持。 PHP-GTK :使用PHP-GTK帮助你方便的创建拥有漂亮GUI(用户图形界面)的PHP应用程序。 

九、PHP在线工具及资源 Minify! 该工具使用 PHP5 开发,用于合并压缩 js/css 文件的应用程序,合并压缩之后的结果可通过 HTTP gzip/deflate 及一些相关头,优化客户端缓存。 HTTP_StaticMerger:CSS和java script文件自动“合并”。 PHP Object Generator 一款PHP代码生成器,它能够为你的PHP4/PHP5应用程序生成简洁和可测试的面向对象代码。 gotAPI/PHP 该工具可以方便的帮助你创建Widget。 koders :开放源代码搜索组件。 PECL :本PHP扩展库含有PHP开发小组提供的不同库的信息。

十、浏览器扩展组件工具(Firefox扩展) FirePHP FirePHP是一款基于Firebug的扩展,可以用来在Firebug的console中方便的输出php的调试信息而又不影响php程序的正常运行。 phpLangEditor 一款PHP函数库解释工具。 PHP Lookup :是一个内置的搜索栏,以帮助您快速查找引用的PHP语法。 PHP Manual Search :一个方便的搜索栏,从您的Web浏览器中搜索官方PHP文档。更多扩展应用请参考:[组图]15款基于浏览器扩展的WEB开发工具 

十一、PHP框架支持 Dwoo :PHP5 的模板引擎。 CodeIgniter 用于敏捷软件开发的PHP框架。 YII Framework :一个高性能的基于组件的PHP框架。 NetBeans :强大的PHP扩展框架支持集,拥有完善的GUI界面,独自成为一款强大的PHP开发工具。 Solar symfony :一个开源的PHP Web框架,加速Web应用程序的创建与维护。 PEAR Propel :一个适用于PHP5的OR映射(Object Relational Mapping)框架。它允许你使用对象代替SQL来读写数据库表格中的行。 {{macro}} template engine Zend Framework :是一个开放源代码的PHP5 开发框架,可用于来开发web 程序和服务。 Qcodo 一个适用于敏捷开发基于PHP5采用MVC架构与CRUD代码生成功能的框架。 SAJAX :Sajax 是一种制作 Ajax 应用程序的模块化方式,通过预定的、动态的函数调用,使得应用程序的开发过程更加平滑。 Smarty : 使用PHP实现MVC开发模式的逻辑层和表示层的模板引擎。 CakePHP 一个开源的PHP on rails的full-stack框架。 Savant2 :一套直接使用PHP function并做了合理的限制的PHP模板引擎。 PHPSpec :一个简洁的PHP框架。 BIWEB :一套最新推出的,针对大型WEB项目设计的开源框架,可承担高负载、大流量、易分流,最大化提升服务器性能,并集成了SEO,WAP,RSS 等当今最流行的功能, 开发WEB应用推荐框架。

十二、PHP集成开发环境(IDE)、编辑器 PHPEclipse 一个强大的Eclipse环境下开发PHP的插件,包括的主要功能有:PHP语法分析,调试,代码格式化,大纲视图,代码模板定制等。 PhpED 一套Windows环境下的PHP集成开发环境。 phpDesigner 一款轻量级的PHP集成开发工具,代码编辑器功能特别强大,支持在线预览。 Zend Studio 一款Eclipse下优秀的PHP开发环境,适用于开发包含丰富接口的RIAs应用程序。 Aptana PHP :优秀的开源IDE开发环境,与Aptana Studio协同工作。 PDT :一款开发工具框架,致力于在Eclipse平台之上提供一个功能完整的PHP集成开发环境。 VS.Php :顾名思义,该插件允许我们在Visual Studio .Net开发工具中集中进行PHP程序开发,例如使用VS.php运行ASAP应用。 PHPEdit :本款IDE工具侧重于提供强大的代码编辑器支持,提供例如语法突出显示、代码提示、代码识别、代码缩进等常用功能,同时集成PHP调试器以及一个用户使用帮助文档生成工具。
posted @ 2009-11-17 22:57 Janpoem 阅读(42) | 评论 (0)编辑

2009年8月2日

    该文被密码保护。
posted @ 2009-08-02 16:20 Janpoem 阅读(9) | 评论 (0)编辑

2009年8月1日

     摘要: 原文:http://hi.baidu.com/dosmark/blog/item/d4528a8b2cf1ead4fc1f10fb.html 安装最新的 JDK 必须安装 Java SE Development Kit (JDK) 6 Update 10 或更新的版本,早期版本对字体反锯齿支持不好。 下载地址:http://java.sun.com/javase/downloads/index....  阅读全文
posted @ 2009-08-01 22:53 Janpoem 阅读(145) | 评论 (0)编辑
     摘要: 第 1 部分: 使用操作码缓存软件提升性能和吞吐量原文:http://www.ibm.com/developerworks/cn/opensource/os-php-fastapps1/PHP 是一种脚本语言,常用于创建 Web 应用程序。它易于掌握,并能迅速生成可视化结果。然而,由于 PHP 是以解释的方式执行的,所以 PHP 代码每次执行时都会被解析和转换成操作码(opcode)。操作码缓存...  阅读全文
posted @ 2009-08-01 02:55 Janpoem 阅读(75) | 评论 (0)编辑

2009年1月23日

     摘要: 终于恨下心将2008删除了,其实从各种角度来说,2008是很棒的,但我工作上的需求更集中倾向于linux系的,越来越需要更加专业化的linux系的工作环境,比如编译,比如基于linux的项目发布与调试。这次我装的是Ubuntu 8.10,这是我计划已久的了。主要是之前几次在虚拟机上安装,对ubuntu的操作也比较熟悉了。就Desktop来说,Ubuntu还是做得有声有色的。apt-get、wget...  阅读全文
posted @ 2009-01-23 23:43 Janpoem 阅读(36) | 评论 (0)编辑

导航

公告

<2010年2月>
31123456
78910111213
14151617181920
21222324252627
28123456
78910111213

统计

搜索

 

常用链接

随笔分类

随笔档案

文章分类

相册

志同道合者

最新评论

阅读排行榜

评论排行榜

60天内阅读排行