来新浪云平台安个家...期待俺有个好应用上线O(∩_∩)O哈!

【转】提高php代码质量 36计

2012年4月9日 没有评论

1.不要使用相对路径

常常会看到:

 

1 require_once('../../lib/some_class.php');

 

该方法有很多缺点:

它首先查找指定的php包含路径, 然后查找当前目录.

因此会检查过多路径.

如果该脚本被另一目录的脚本包含, 它的基本目录变成了另一脚本所在的目录.

另一问题, 当定时任务运行该脚本, 它的上级目录可能就不是工作目录了.

因此最佳选择是使用绝对路径:

 

1 define('ROOT' , '/var/www/project/');
2 require_once(ROOT . '../../lib/some_class.php');
3
4 //rest of the code

 

 

我们定义了一个绝对路径, 值被写死了. 我们还可以改进它. 路径 /var/www/project 也可能会改变, 那么我们每次都要改变它吗? 不是的, 我们可以使用__FILE__常量, 如:

 

1 //suppose your script is /var/www/project/index.php
2 //Then __FILE__ will always have that full path.
3
4 define('ROOT' , pathinfo(__FILE__, PATHINFO_DIRNAME));
5 require_once(ROOT . '../../lib/some_class.php');
6
7 //rest of the code

 

现在, 无论你移到哪个目录, 如移到一个外网的服务器上, 代码无须更改便可正确运行.

2. 不要直接使用 require, include, include_once, required_once

可以在脚本头部引入多个文件, 像类库, 工具文件和助手函数等, 如:

 

1 require_once('lib/Database.php');
2 require_once('lib/Mail.php');
3
4 require_once('helpers/utitlity_functions.php');

 

这种用法相当原始. 应该更灵活点. 应编写个助手函数包含文件. 例如:

 

1 function load_class($class_name)
2 {
3     //path to the class file
4     $path = ROOT . '/lib/' . $class_name . '.php');
5     require_once( $path );
6 }
7
8 load_class('Database');
9 load_class('Mail');

 

有什么不一样吗? 该代码更具可读性.

將来你可以按需扩展该函数, 如:

 

01 function load_class($class_name)
02 {
03     //path to the class file
04     $path = ROOT . '/lib/' . $class_name . '.php');
05
06     if(file_exists($path))
07     {
08         require_once( $path );
09     }
10 }

 

还可做得更多:

为同样文件查找多个目录

能很容易的改变放置类文件的目录, 无须在代码各处一一修改

可使用类似的函数加载文件, 如html内容.

3. 为应用保留调试代码

在开发环境中, 我们打印数据库查询语句, 转存有问题的变量值, 而一旦问题解决, 我们注释或删除它们. 然而更好的做法是保留调试代码.

在开发环境中, 你可以:

 

01 define('ENVIRONMENT' , 'development');
02
03 if(! $db->query( $query )
04 {
05     if(ENVIRONMENT == 'development')
06     {
07         echo "$query failed";
08     }
09     else
10     {
11         echo "Database error. Please contact administrator";
12     }
13 }

 

在服务器中, 你可以:

 

01 define('ENVIRONMENT' , 'production');
02
03 if(! $db->query( $query )
04 {
05     if(ENVIRONMENT == 'development')
06     {
07         echo "$query failed";
08     }
09     else
10     {
11         echo "Database error. Please contact administrator";
12     }
13 }

 

4. 使用可跨平台的函数执行命令

system, exec, passthru, shell_exec 这4个函数可用于执行系统命令. 每个的行为都有细微差别. 问题在于, 当在共享主机中, 某些函数可能被选择性的禁用. 大多数新手趋于每次首先检查哪个函数可用, 然而再使用它.

更好的方案是封成函数一个可跨平台的函数.

 

01 /**
02     Method to execute a command in the terminal
03     Uses :
04
05     1. system
06     2. passthru
07     3. exec
08     4. shell_exec
09
10 */
11 function terminal($command)
12 {
13     //system
14     if(function_exists('system'))
15     {
16         ob_start();
17         system($command , $return_var);
18         $output = ob_get_contents();
19         ob_end_clean();
20     }
21     //passthru
22     else if(function_exists('passthru'))
23     {
24         ob_start();
25         passthru($command , $return_var);
26         $output = ob_get_contents();
27         ob_end_clean();
28     }
29
30     //exec
31     else if(function_exists('exec'))
32     {
33         exec($command , $output , $return_var);
34         $output = implode("\n" , $output);
35     }
36
37     //shell_exec
38     else if(function_exists('shell_exec'))
39     {
40         $output = shell_exec($command) ;
41     }
42
43     else
44     {
45         $output = 'Command execution not possible on this system';
46         $return_var = 1;
47     }
48
49     return array('output' => $output , 'status' => $return_var);
50 }
51
52 terminal('ls');

 

上面的函数將运行shell命令, 只要有一个系统函数可用, 这保持了代码的一致性.

5. 灵活编写函数

 

1 function add_to_cart($item_id , $qty)
2 {
3     $_SESSION['cart']['item_id'] = $qty;
4 }
5
6 add_to_cart( 'IPHONE3' , 2 );

 

使用上面的函数添加单个项目. 而当添加项列表的时候,你要创建另一个函数吗? 不用, 只要稍加留意不同类型的参数, 就会更灵活. 如:

 

01 function add_to_cart($item_id , $qty)
02 {
03     if(!is_array($item_id))
04     {
05         $_SESSION['cart']['item_id'] = $qty;
06     }
07
08     else
09     {
10         foreach($item_id as $i_id => $qty)
11         {
12             $_SESSION['cart']['i_id'] = $qty;
13         }
14     }
15 }
16
17 add_to_cart( 'IPHONE3' , 2 );
18 add_to_cart( array('IPHONE3' => 2 , 'IPAD' => 5) );

 

现在, 同个函数可以处理不同类型的输入参数了. 可以参照上面的例子重构你的多处代码, 使其更智能.

6. 有意忽略php关闭标签

我很想知道为什么这么多关于php建议的博客文章都没提到这点.

 

1 <?php
2
3 echo "Hello";
4
5 //Now dont close this tag

 

这將节约你很多时间. 我们举个例子:

 

一个 super_class.php 文件

 

01 <?php
02 class super_class
03 {
04     function super_function()
05     {
06         //super code
07     }
08 }
09 ?>
10 //super extra character after the closing tag

 

index.php

 

 

1 require_once('super_class.php');
2
3 //echo an image or pdf , or set the cookies or session data

 

这样, 你將会得到一个 Headers already send error. 为什么? 因为 “super extra character” 已经被输出了. 现在你得开始调试啦. 这会花费大量时间寻找 super extra 的位置.

因此, 养成省略关闭符的习惯:

 

01 <?php
02 class super_class
03 {
04     function super_function()
05     {
06         //super code
07     }
08 }
09
10 //No closing tag

 

这会更好.

 

 

7. 在某地方收集所有输入, 一次输出给浏览器

这称为输出缓冲, 假如说你已在不同的函数输出内容:

 

01 function print_header()
02 {
03     echo "<div id='header'>Site Log and Login links</div>";
04 }
05
06 function print_footer()
07 {
08     echo "<div id='footer'>Site was made by me</div>";
09 }
10
11 print_header();
12 for($i = 0 ; $i < 100; $i++)
13 {
14     echo "I is : $i <br />';
15 }
16 print_footer();

 

替代方案, 在某地方集中收集输出. 你可以存储在函数的局部变量中, 也可以使用ob_start和ob_end_clean. 如下:

 

01 function print_header()
02 {
03     $o = "<div id='header'>Site Log and Login links</div>";
04     return $o;
05 }
06
07 function print_footer()
08 {
09     $o = "<div id='footer'>Site was made by me</div>";
10     return $o;
11 }
12
13 echo print_header();
14 for($i = 0 ; $i < 100; $i++)
15 {
16     echo "I is : $i <br />';
17 }
18 echo print_footer();

 

为什么需要输出缓冲:

>>可以在发送给浏览器前更改输出. 如 str_replaces 函数或可能是 preg_replaces 或添加些监控/调试的html内容.

>>输出给浏览器的同时又做php的处理很糟糕. 你应该看到过有些站点的侧边栏或中间出现错误信息. 知道为什么会发生吗? 因为处理和输出混合了.

8. 发送正确的mime类型头信息, 如果输出非html内容的话.

输出一些xml.

 

1 $xml = '<?xml version="1.0" encoding="utf-8" standalone="yes"?>';
2 $xml = "<response>
3   <code>0</code>
4 </response>";
5
6 //Send xml data
7 echo $xml;

 

工作得不错. 但需要一些改进.

 

1 $xml = '<?xml version="1.0" encoding="utf-8" standalone="yes"?>';
2 $xml = "<response>
3   <code>0</code>
4 </response>";
5
6 //Send xml data
7 header("content-type: text/xml");
8 echo $xml;

 

注意header行. 该行告知浏览器发送的是xml类型的内容. 所以浏览器能正确的处理. 很多的javascript库也依赖头信息.

类似的有 javascript , css, jpg image, png image:

JavaScript

 

1 header("content-type: application/x-javascript");
2 echo "var a = 10";

 

CSS

 

1 header("content-type: text/css");
2 echo "#div id { background:#000; }";

 

9. 为mysql连接设置正确的字符编码

曾经遇到过在mysql表中设置了unicode/utf-8编码, phpadmin也能正确显示, 但当你获取内容并在页面输出的时候,会出现乱码. 这里的问题出在mysql连接的字符编码.

 

01 //Attempt to connect to database
02 $c = mysqli_connect($this->host , $this->username, $this->password);
03
04 //Check connection validity
05 if (!$c)&nbsp;
06 {
07     die ("Could not connect to the database host: <br />". mysqli_connect_error());
08 }
09
10 //Set the character set of the connection
11 if(!mysqli_set_charset ( $c , 'UTF8' ))
12 {
13     die('mysqli_set_charset() failed');
14 }

 

一旦连接数据库, 最好设置连接的 characterset. 你的应用如果要支持多语言, 这么做是必须的.

10. 使用 htmlentities 设置正确的编码选项

php5.4前, 字符的默认编码是ISO-8859-1, 不能直接输出如À â等.

 

1 $value = htmlentities($this->value , ENT_QUOTES , CHARSET);

 

php5.4以后, 默认编码为UTF-8, 这將解决很多问题. 但如果你的应用是多语言的, 仍然要留意编码问题,.

11. 不要在应用中使用gzip压缩输出, 让apache处理

考虑过使用 ob_gzhandler 吗? 不要那样做. 毫无意义. php只应用来编写应用. 不应操心服务器和浏览器的数据传输优化问题.

使用apache的mod_gzip/mod_deflate 模块压缩内容.

12. 使用json_encode输出动态javascript内容

时常会用php输出动态javascript内容:

 

01 $images = array(
02 'myself.png' , 'friends.png' , 'colleagues.png'
03 );
04
05 $js_code = '';
06
07 foreach($images as $image)
08 {
09 $js_code .= "'$image' ,";
10 }
11
12 $js_code = 'var images = [' . $js_code . ']; ';
13
14 echo $js_code;
15
16 //Output is var images = ['myself.png' ,'friends.png' ,'colleagues.png' ,];

 

更聪明的做法, 使用 json_encode:

 

1 $images = array(
2 'myself.png' , 'friends.png' , 'colleagues.png'
3 );
4
5 $js_code = 'var images = ' . json_encode($images);
6
7 echo $js_code;
8
9 //Output is : var images = ["myself.png","friends.png","colleagues.png"]

 

优雅乎?

13. 写文件前, 检查目录写权限

写或保存文件前, 确保目录是可写的, 假如不可写, 输出错误信息. 这会节约你很多调试时间. linux系统中, 需要处理权限, 目录权限不当会导致很多很多的问题, 文件也有可能无法读取等等.

确保你的应用足够智能, 输出某些重要信息.

 

1 $contents = "All the content";
2 $file_path = "/var/www/project/content.txt";
3
4 file_put_contents($file_path , $contents);

 

这大体上正确. 但有些间接的问题. file_put_contents 可能会由于几个原因失败:

>>父目录不存在

>>目录存在, 但不可写

>>文件被写锁住?

所以写文件前做明确的检查更好.

 

01 $contents = "All the content";
02 $dir = '/var/www/project';
03 $file_path = $dir . "/content.txt";
04
05 if(is_writable($dir))
06 {
07     file_put_contents($file_path , $contents);
08 }
09 else
10 {
11     die("Directory $dir is not writable, or does not exist. Please check");
12 }

 

这么做后, 你会得到一个文件在何处写及为什么失败的明确信息.

14. 更改应用创建的文件权限

在linux环境中, 权限问题可能会浪费你很多时间. 从今往后, 无论何时, 当你创建一些文件后, 确保使用chmod设置正确权限. 否则的话, 可能文件先是由”php”用户创建, 但你用其它的用户登录工作, 系统將会拒绝访问或打开文件, 你不得不奋力获取root权限,  更改文件的权限等等.

 

1 // Read and write for owner, read for everybody else
2 chmod("/somedir/somefile", 0644);
3
4 // Everything for owner, read and execute for others
5 chmod("/somedir/somefile", 0755);

 

15. 不要依赖submit按钮值来检查表单提交行为

 

1 if($_POST['submit'] == 'Save')
2 {
3     //Save the things
4 }

 

上面大多数情况正确, 除了应用是多语言的. ‘Save’ 可能代表其它含义. 你怎么区分它们呢. 因此, 不要依赖于submit按钮的值.

 

1 if( $_SERVER['REQUEST_METHOD'] == 'POST' and isset($_POST['submit']) )
2 {
3     //Save the things
4 }

 

现在你从submit按钮值中解脱出来了.

16. 为函数内总具有相同值的变量定义成静态变量

 

1 //Delay for some time
2 function delay()
3 {
4     $sync_delay = get_option('sync_delay');
5
6     echo "<br />Delaying for $sync_delay seconds...";
7     sleep($sync_delay);
8     echo "Done <br />";
9 }

 

用静态变量取代:

 

01 //Delay for some time
02 function delay()
03 {
04     static $sync_delay = null;
05
06     if($sync_delay == null)
07     {
08     $sync_delay = get_option('sync_delay');
09     }
10
11     echo "<br />Delaying for $sync_delay seconds...";
12     sleep($sync_delay);
13     echo "Done <br />";
14 }

 

17. 不要直接使用 $_SESSION 变量

某些简单例子:

 

1 $_SESSION['username'] = $username;
2 $username = $_SESSION['username'];

 

这会导致某些问题. 如果在同个域名中运行了多个应用, session 变量可能会冲突. 两个不同的应用可能使用同一个session key. 例如, 一个前端门户, 和一个后台管理系统使用同一域名.

从现在开始, 使用应用相关的key和一个包装函数:

 

01 define('APP_ID' , 'abc_corp_ecommerce');
02
03 //Function to get a session variable
04 function session_get($key)
05 {
06     $k = APP_ID . '.' . $key;
07
08     if(isset($_SESSION[$k]))
09     {
10         return $_SESSION[$k];
11     }
12
13     return false;
14 }
15
16 //Function set the session variable
17 function session_set($key , $value)
18 {
19     $k = APP_ID . '.' . $key;
20     $_SESSION[$k] = $value;
21
22     return true;
23 }

 

18. 將工具函数封装到类中

假如你在某文件中定义了很多工具函数:

 

01 function utility_a()
02 {
03     //This function does a utility thing like string processing
04 }
05
06 function utility_b()
07 {
08     //This function does nother utility thing like database processing
09 }
10
11 function utility_c()
12 {
13     //This function is ...
14 }

 

这些函数的使用分散到应用各处. 你可能想將他们封装到某个类中:

 

01 class Utility
02 {
03     public static function utility_a()
04     {
05
06     }
07
08     public static function utility_b()
09     {
10
11     }
12
13     public static function utility_c()
14     {
15
16     }
17 }
18
19 //and call them as
20
21 $a = Utility::utility_a();
22 $b = Utility::utility_b();

 

显而易见的好处是, 如果php内建有同名的函数, 这样可以避免冲突.

另一种看法是, 你可以在同个应用中为同个类维护多个版本, 而不导致冲突. 这是封装的基本好处, 无它.

19. Bunch of silly tips

>>使用echo取代print

>>使用str_replace取代preg_replace, 除非你绝对需要

>>不要使用 short tag

>>简单字符串用单引号取代双引号

>>head重定向后记得使用exit

>>不要在循环中调用函数

>>isset比strlen快

>>始中如一的格式化代码

>>不要删除循环或者if-else的括号

不要这样写代码:

 

1 <span style="color: rgb(51, 51, 51);">if($a == true) $a_count++;</span>

 

这绝对WASTE.

写成:

 

1 <span style="color: rgb(51, 51, 51);">if($a == true)
2 {
3     $a_count++;
4 }</span>

 

不要尝试省略一些语法来缩短代码. 而是让你的逻辑简短.

>>使用有高亮语法显示的文本编辑器. 高亮语法能让你减少错误.

 

20. 使用array_map快速处理数组

比如说你想 trim 数组中的所有元素. 新手可能会:

 

1 foreach($arr as $c => $v)
2 {
3     $arr[$c] = trim($v);
4 }

 

但使用 array_map 更简单:

1 $arr = array_map('trim' , $arr);

这会为$arr数组的每个元素都申请调用trim. 另一个类似的函数是 array_walk. 请查阅文档学习更多技巧.

21. 使用 php filter 验证数据

你肯定曾使用过正则表达式验证 email , ip地址等. 是的,每个人都这么使用. 现在, 我们想做不同的尝试, 称为filter.

php的filter扩展提供了简单的方式验证和检查输入.

22. 强制类型检查

 

1 $amount = intval( $_GET['amount'] );
2 $rate = (int) $_GET['rate'];

 

这是个好习惯.

23. 如果需要,使用profiler如xdebug

如果你使用php开发大型的应用, php承担了很多运算量, 速度会是一个很重要的指标. 使用profile帮助优化代码. 可使用

xdebug和webgrid.

24. 小心处理大数组

对于大的数组和字符串, 必须小心处理. 常见错误是发生数组拷贝导致内存溢出,抛出Fatal Error of Memory size 信息:

 

1 $db_records_in_array_format; //This is a big array holding 1000 rows from a table each having 20 columns , every row is atleast 100 bytes , so total 1000 * 20 * 100 = 2MB
2
3 $cc = $db_records_in_array_format; //2MB more
4
5 some_function($cc); //Another 2MB ?

 

当导入或导出csv文件时, 常常会这么做.

不要认为上面的代码会经常因内存限制导致脚本崩溃. 对于小的变量是没问题的, 但处理大数组的时候就必须避免.

确保通过引用传递, 或存储在类变量中:

 

1 $a = get_large_array();
2 pass_to_function(&$a);

 

这么做后, 向函数传递变量引用(而不是拷贝数组). 查看文档.

 

01 class A
02 {
03     function first()
04     {
05         $this->a = get_large_array();
06         $this->pass_to_function();
07     }
08
09     function pass_to_function()
10     {
11         //process $this->a
12     }
13 }

 

尽快的 unset 它们, 让内存得以释放,减轻脚本负担.

25.  由始至终使用单一数据库连接

确保你的脚本由始至终都使用单一的数据库连接. 在开始处正确的打开连接, 使用它直到结束, 最后关闭它. 不要像下面这样在函数中打开连接:

 

01 function add_to_cart()
02 {
03     $db = new Database();
04     $db->query("INSERT INTO cart .....");
05 }
06
07 function empty_cart()
08 {
09     $db = new Database();
10     $db->query("DELETE FROM cart .....");
11 }

 

 

使用多个连接是个糟糕的, 它们会拖慢应用, 因为创建连接需要时间和占用内存.

特定情况使用单例模式, 如数据库连接.

26. 避免直接写SQL, 抽象之

不厌其烦的写了太多如下的语句:

 

1 <span style="color: rgb(51, 51, 51);">$query = "INSERT INTO users(name , email , address , phone) VALUES('$name' , '$email' , '$address' , '$phone')";
2 $db->query($query); //call to mysqli_query()</span>

 

这不是个建壮的方案. 它有些缺点:

>>每次都手动转义值

>>验证查询是否正确

>>查询的错误会花很长时间识别(除非每次都用if-else检查)

>>很难维护复杂的查询

因此使用函数封装:

 

01 <span style="color: rgb(51, 51, 51);">function insert_record($table_name , $data)
02 {
03     foreach($data as $key => $value)
04     {
05     //mysqli_real_escape_string
06         $data[$key] = $db->mres($value);
07     }
08
09     $fields = implode(',' , array_keys($data));
10     $values = "'" . implode("','" , array_values($data)) . "'";
11
12     //Final query
13     $query = "INSERT INTO {$table}($fields) VALUES($values)";
14
15     return $db->query($query);
16 }
17
18 $data = array('name' => $name , 'email' => $email  , 'address' => $address , 'phone' => $phone);
19
20 insert_record('users' , $data);</span>

 

看到了吗? 这样会更易读和扩展. record_data 函数小心的处理了转义.

最大的优点是数据被预处理为一个数组, 任何语法错误都会被捕获.

该函数应该定义在某个database类中, 你可以像 $db->insert_record这样调用.

查看本文, 看看怎样让你处理数据库更容易.

类似的也可以编写update,select,delete方法. 试试吧.

27. 將数据库生成的内容缓存到静态文件中

如果所有的内容都是从数据库获取的, 它们应该被缓存. 一旦生成了, 就將它们保存在临时文件中. 下次请求该页面时, 可直接从缓存中取, 不用再查数据库.

好处:

>>节约php处理页面的时间, 执行更快

>>更少的数据库查询意味着更少的mysql连接开销

28. 在数据库中保存session

基于文件的session策略会有很多限制. 使用基于文件的session不能扩展到集群中, 因为session保存在单个服务器中. 但数据库可被多个服务器访问, 这样就可以解决问题.

在数据库中保存session数据, 还有更多好处:

>>处理username重复登录问题. 同个username不能在两个地方同时登录.

>>能更准备的查询在线用户状态.

29. 避免使用全局变量

>>使用 defines/constants

>>使用函数获取值

>>使用类并通过$this访问

30. 在head中使用base标签

没听说过? 请看下面:

 

1 <head>
2 <base href="http://www.domain.com/store/">
3 </head>
4 <body>
5 <img src="happy.jpg" />
6 </body>
7 </html>

 

base 标签非常有用. 假设你的应用分成几个子目录, 它们都要包括相同的导航菜单.

www.domain.com/store/home.php

www.domain.com/store/products/ipad.php

在首页中, 可以写:

 

1 <a href="home.php">Home</a>
2 <a href="products/ipad.php">Ipad</a>

 

但在你的ipad.php不得不写成:

 

1 <span style="color: rgb(51, 51, 51);"><a href="../home.php">Home</a>
2 <a href="ipad.php">Ipad</a></span>

 

因为目录不一样. 有这么多不同版本的导航菜单要维护, 很糟糕啊.

因此, 请使用base标签.

 

1 <span style="color: rgb(51, 51, 51);"><head>
2 <base href="http://www.domain.com/store/">
3 </head>
4 <body>
5 <a href="home.php">Home</a>
6 <a href="products/ipad.php">Ipad</a>
7 </body>
8 </html></span>

 

现在, 这段代码放在应用的各个目录文件中行为都一致.

31. 永远不要將 error_reporting 设为 0

关闭不相的错误报告. E_FATAL 错误是很重要的.

 

1 <span style='color: rgb(51, 51, 51); font-family: "Helvetica, Arial, sans-serif";'>ini_set('display_errors', 1);
2 error_reporting(~E_WARNING & ~E_NOTICE & ~E_STRICT);</span>

 

32. 注意平台体系结构

integer在32位和64位体系结构中长度是不同的. 因此某些函数如 strtotime 的行为会不同.

在64位的机器中, 你会看到如下的输出.

 

1 <span style="color: rgb(51, 51, 51);">$ php -a
2 Interactive shell
3
4 php > echo strtotime("0000-00-00 00:00:00");
5 -62170005200
6 php > echo strtotime('1000-01-30');
7 -30607739600
8 php > echo strtotime('2100-01-30');
9 4104930600</span>

 

但在32位机器中, 它们將是bool(false). 查看这里, 了解更多.

33. 不要过分依赖 set_time_limit

如果你想限制最小时间, 可以使用下面的脚本:

 

1 <span style="color: rgb(51, 51, 51);">set_time_limit(30);
2
3 //Rest of the code</span>

 

高枕无忧吗?  注意任何外部的执行, 如系统调用,socket操作, 数据库操作等, 就不在set_time_limits的控制之下.

因此, 就算数据库花费了很多时间查询, 脚本也不会停止执行. 视情况而定.

34. 使用扩展库

一些例子:

>>mPDF — 能通过html生成pdf文档

>>PHPExcel — 读写excel

>>PhpMailer — 轻松处理发送包含附近的邮件

>>pChart — 使用php生成报表

使用开源库完成复杂任务, 如生成pdf, ms-excel文件, 报表等.

35. 使用MVC框架

是时候使用像 codeigniter 这样的MVC框架了. MVC框架并不强迫你写面向对象的代码. 它们仅將php代码与html分离.

>>明确区分php和html代码. 在团队协作中有好处, 设计师和程序员可以同时工作.

>>面向对象设计的函数能让你更容易维护

>>内建函数完成了很多工作, 你不需要重复编写

>>开发大的应用是必须的

>>很多建议, 技巧和hack已被框架实现了

36. 时常看看 phpbench

phpbench 提供了些php基本操作的基准测试结果, 它展示了一些徽小的语法变化是怎样导致巨大差异的.

查看php站点的评论, 有问题到IRC提问, 时常阅读开源代码, 使用Linux开发.

OSCHINA原创翻译,转载请注明出处: OSCHINA

英文原文

分类: PHP+ 标签:

【转】十大互联网创业土包思维

2012年3月15日 没有评论
 
1。又要马跑得快,又不给马吃肥草。 --- 最土包的思维,只有一个结果,军心不稳,离职率高,关门大吉。

 
2。我有些闲钱,想试试水。 --- 跟这类人合作,只有一个结果,钱真的变成水了,泡都不冒,因为创业无后路。
3。先开公司,再找项目。--- 莫癫了。
4。花最便宜的钱找几个菜鸟级临时工,先搞出来再说。 --- 象棋高手,可以车轮战连挑数人,并且全部获胜。明白吗?网站虽然门槛不高,但组建一个由高手组 成的团队,是基本保证。
5。搞技术的大把,好招。--- 对,但是,初创团队的每一个人都很关键,失去他的时候,你才会体会,后悔莫及。
6。我是创业公司,所以我给的待遇就一定要低。--- 员工会想,因为是创业公司,所以我可以随时走。
7。只要坚持,一定成功。--- 全世界的人都这么想。
8。别人没做过的,我们就搞! --- 你的智商有200吗?
9。因为我出钱,你是员工,所以你帮我全部搞定,我忙我的。--- 很遗憾,因为我不出钱,所以我无所谓。
10。多试几个,总会找到一个的。--- 好吧,你找到了,再找我。

 

来源:http://my.oschina.net/dongming/blog/49208

【转】Linux系统基础网络配置老鸟精华篇

2012年2月25日 没有评论

目录:
1)配置修改主机名hostname
2)网卡配置文件说明:
3)配置修改ip地址
4)配置修改网关gateway
5) 配置修改DNS
6)查看ip、网关或路由、DNS配置
a.[查看ip配置方法]
b.[查看网关和路由方法]
c.[查看dns配置方法]
7)如果win32和linux服务器无法连接网络,分别描述排查方法?

##########################
####1)配置修改主机名:
##########################
临时方法:
hostname oldboy
退出当前shell重新登陆即可生效。此法只能临时修改生效,重起系统后失效。
提示:很多人使用hostname 主机名来修改,其实这个只是做为暂时的,重启后将恢复到配置前的主机名.

永久方法:
法一:
步骤1:
vi /etc/sysconfig/network
将里面的HOSTNAME=XX改成HOSTNAME=oldboy,然后保存。
提示:这里改完后,执行/etc/init.d/network restart或 source /etc/sysconfig/network等做法都不生效
如果要单一的修改这个文件可能就需要重起服务器了。
题外话:这里应该是有一个直接生效的方法的系统自带的当前及永久生效方法的,就是就是加载下hostname调用下配置文件的命令执行下就好,
把这个问题留给大家了!

步骤2:
然后通过命令行继续修改:hostname oldboy ,完成后退出重新登陆即生效
提示:这样就能保证临时生效,重起系统系统也生效了。

法二:
即时永久都生效的另外改法:执行setup-网络配置– Edit DNS configuration–>

DNS configuration
x                               x
x Hostname      oldboy_______   x ===========>修改这里
x Primary DNS   202.106.0.20___ x
x Secondary DNS 211.147.6.3____ x
x Tertiary DNS  _______________ x
x Search        _______________ x
提示:在这里改完保存后会及时生效,重起也生效,从这就可以看出来,系统还是有直接临时永久都生效的方法。

特别说明:使用以上的方法都可能导致/etc/hosts中的127.0.0.1对应的主机名未修改,此时,应该手动修改:如:
[root@oldboy ~]# cat /etc/hosts
# Do not remove the following line, or various programs
# that require network functionality will fail.
127.0.0.1              oldboy localhost.localdomain localhost ===========>修改这里的oldboy
::1             localhost6.localdomain6 localhost6
10.0.0.190  www.etiantian.org
提示:如果/etc/hosts不改,以后会遇到一些问题,如sendmail启动缓慢,ldap服务解析缓慢,sudo切用户缓慢等等都是主机名和/etc/hosts中的解析不对应导致的。

拓展:有关重起系统设置主机名的脚本:
[root@oldboy ~]# grep -i hostname /etc/rc.d/rc.sysinit
HOSTNAME=`/bin/hostname`
if [ -z "$HOSTNAME" -o "$HOSTNAME" = "(none)" ]; then
HOSTNAME=localhost
# Set the hostname.
update_boot_stage RChostname
action $”Setting hostname ${HOSTNAME}: ” hostname ${HOSTNAME} ===========>这里就是系统重起后执行rc.sysinit后修改机器名的地方。
# Use the network address to set the hostname of the client.  This
if [ "$HOSTNAME" = "localhost" -o "$HOSTNAME" = "localhost.localdomain" ]; then
hostname ${HOSTNAME}
mount -t nfs $CLIENTSTATE/$HOSTNAME $STATE_MOUNT -o rw,nolock
# Reset the hostname.
action $”Resetting hostname ${HOSTNAME}: ” hostname ${HOSTNAME}
[root@oldboy ~]# grep -i hostname /etc/rc.d/init.d/network ===========>这里没有和主机名相关的信息。

################################
####2)网卡配置文件说明:
################################

[root@oldboy ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth0 ==》这里是eth0网卡设备的默认配置文件
# Advanced Micro Devices [AMD] 79c970 [PCnet32 LANCE]
DEVICE=eth0 ================》这里是网卡名称第一块网卡为eth0,第二块为eth1…
BOOTPROTO=static============》static为固定IP地址,非动态DHCP获取
BROADCAST=10.0.0.255 =======》这里是广播地址,一般为网络地址的最后一个地址。
HWADDR=00:0C:29:0E:5F:63 ===》这里mac地址,不同的机器不能重复,尤其是在刻隆虚拟机或复制网卡配置时要注意。
IPADDR=10.0.0.161 ==========》这里是IP地址
NETMASK=255.255.255.0=======》子网掩码/24
NETWORK=10.0.0.0   =========》网段设置
ONBOOT=yes =================》开机网卡自启动
GATEWAY=10.0.0.254==========》网关的配置,也可以命令行通过route添加删除。
TYPE=Ethernet===============》类型
提示:第一块网卡为ifcfg-eth0,第二块为ifcfg-eth1…

################################
####3)配置修改ip地址:
################################
配置服务器IP及DNS等网络配置的方法:
1)setup-网络配置,然后修改。
2)直接编辑或手写上面配置文件。
/etc/sysconfig/network-scripts/ifcfg-eth0 ===============》网卡配置
/etc/resolv.conf===============》DNS client的配置

提示:以上两个方法一般需要重起或者重新加载/etc/init.d/network restart 或/etc/init.d/network reload才能生效。

##########################
####4)配置修改网关gw:
##########################
法一:修改/etc/sysconfig/network
[root@oldboy network-scripts]# cat /etc/sysconfig/network
NETWORKING=yes
NETWORKING_IPV6=no
HOSTNAME=oldboy
GATEWAY=10.0.0.254 ====》这个就是网关的配置
提示;需要执行/etc/init.d/network reload 即可生效。

法二:修改/etc/sysconfig/network-scripts/ifcfg-eth0
[root@oldboy network-scripts]# cat ifcfg-eth0
# Advanced Micro Devices [AMD] 79c970 [PCnet32 LANCE]
DEVICE=eth0
BOOTPROTO=static
BROADCAST=10.0.0.255
HWADDR=00:0C:29:0E:5F:63
IPADDR=10.0.0.161
NETMASK=255.255.255.0
NETWORK=10.0.0.0
ONBOOT=yes
GATEWAY=10.0.0.254====》这个就是增加网关的配置,默认没有
提示;需要执行/etc/init.d/network restart 或reload 即可生效。

特别注意:
1)/etc/sysconfig/network-scripts/ifcfg-eth0中的网关配置优先于/etc/init.d/network
2)注意配置的大小写,gATEWAY=10.0.0.254这样的小写格式就不对。

法三:通过命令修改默认网关:
[root@oldboy network-scripts]# route del default gw 10.0.0.254 ==》首先删除之
[root@oldboy network-scripts]# route -n ==》查看命令
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
10.0.0.0        0.0.0.0         255.255.255.0   U     0      0        0 eth0
169.254.0.0     0.0.0.0         255.255.0.0     U     0      0        0 eth0
[root@oldboy network-scripts]# route add default gw 10.0.0.254 ==》添加默认网关
[root@oldboy network-scripts]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
10.0.0.0        0.0.0.0         255.255.255.0   U     0      0        0 eth0
169.254.0.0     0.0.0.0         255.255.0.0     U     0      0        0 eth0
0.0.0.0         10.0.0.254      0.0.0.0         UG    0      0        0 eth0
注意:此修改为临时修改,重新加载或启动网卡后就会失效,解决方法就是尽量在配置文件里配置,
实在有需求就把route add default gw 10.0.0.254放到rc.local自启动文件里或/etc/init.d/network网卡
restart/reload段脚本配置里实现开机自启动或重起网卡也生效,这也有点太复杂了,咱就别这样做了,好不?

##########################
####5)修改主机DNS配置
##########################
法一:setup–网络配置图形操作

法二:修改/etc/resolv.conf ==》这里主机DNS配置文件的路径
[root@oldboy network-scripts]# cat /etc/resolv.conf
nameserver 202.106.0.20
nameserver 8.8.8.8
nameserver 211.147.6.3
提示:每个配置一行这个resolv.conf修改后直接生效,注意,不是nameservers,
另,这个配置文件也是有知识的,同学们可以man resolv.conf查看。

##########################
###6)查看ip、网关或路由、DNS配置:
##########################

[a.查看ip配置方法]
[root@oldboy ~]# ifconfig ==》直接命令名表示显示所有网卡IP
eth0      Link encap:Ethernet  HWaddr 00:0C:29:1D:28:D5
inet addr:10.0.0.190  Bcast:10.0.0.255  Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fe1d:28d5/64 Scope:Link
UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
RX packets:4154 errors:0 dropped:0 overruns:0 frame:0
TX packets:3107 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:367589 (358.9 KiB)  TX bytes:481210 (469.9 KiB)
Interrupt:185 Base address:0×1400

lo        Link encap:Local Loopback
inet addr:127.0.0.1  Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING  MTU:16436  Metric:1
RX packets:36 errors:0 dropped:0 overruns:0 frame:0
TX packets:36 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:3744 (3.6 KiB)  TX bytes:3744 (3.6 KiB)

[root@oldboy ~]# ifconfig eth0 ==》显示指定网卡IP
eth0      Link encap:Ethernet  HWaddr 00:0C:29:1D:28:D5
inet addr:10.0.0.190  Bcast:10.0.0.255  Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fe1d:28d5/64 Scope:Link
UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
RX packets:4170 errors:0 dropped:0 overruns:0 frame:0
TX packets:3130 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:368687 (360.0 KiB)  TX bytes:484496 (473.1 KiB)
Interrupt:185 Base address:0×1400

[b.查看网关和路由方法]
[root@oldboy network-scripts]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
10.0.0.0        0.0.0.0         255.255.255.0   U     0      0        0 eth0
169.254.0.0     0.0.0.0         255.255.0.0     U     0      0        0 eth0
0.0.0.0         10.0.0.254      0.0.0.0         UG    0      0        0 eth0

[root@oldboy ~]# netstat -rn  ==》此法可以不记,记route -n即可。
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
10.0.0.0        0.0.0.0         255.255.255.0   U         0 0          0 eth0
169.254.0.0     0.0.0.0         255.255.0.0     U         0 0          0 eth0

查看linux命令帮助的命令man or info or命令 –help:
例:查看route用法
man route 和 info route 或route –help
route功能强大,同学们要熟练掌握,上面仅是一个简单的用法。

[c.查看DNS配置方法]
[root@oldboy ~]# cat /etc/resolv.conf ==》这是常见的检查方法
nameserver 202.106.0.20
[root@oldboy ~]# ping g.cn ==》这是常见的检查方法,返回ip地址了说明通的。
PING g.cn (74.125.71.160) 56(84) bytes of data.
64 bytes from hx-in-f160.1e100.net (74.125.71.160): icmp_seq=1 ttl=49 time=51.7 ms

[root@oldboy ~]# host www.etiantian.org ==》这是常见的检查方法,返回ip地址了说明dns通的。
www.etiantian.org has address 211.100.98.99

— g.cn ping statistics —
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 51.710/51.710/51.710/0.000 ms
[root@oldboy ~]# dig www.etiantian.org

; <<>> DiG 9.3.6-P1-RedHat-9.3.6-4.P1.el5 <<>> www.etiantian.org
;; global options:  printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 45736
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;www.etiantian.org.             IN      A

;; ANSWER SECTION:
www.etiantian.org.      600     IN      A       211.100.98.99

;; Query time: 90 msec
;; SERVER: 202.106.0.20#53(202.106.0.20)
;; WHEN: Mon Feb 20 11:50:57 2012
;; MSG SIZE  rcvd: 51

[root@oldboy ~]# nslookup
> www.etiantian.org
Server:         202.106.0.20
Address:        202.106.0.20#53

Non-authoritative answer:
Name:   www.etiantian.org
Address: 211.100.98.99

7)如果win32和linux服务器无法连接网络,分别描述排查方法?
   此题留给大家了。大家可以评论或单独和我交流。
提示:基本检查思路:
a.物理链路是否通畅
b.本机IP,路由,DNS的设置情况是否达标。
c.测试到网关或路由器的通畅情况。
d.测试ping公网ip的通常情况(平时要记几个外部IP)
e.测试DNS的通畅,可以ping etiantian.org看是否出对应IP。
根据每级的结果来排查,如果是系统管理员,以上问题都检查了后,还可以在网关路由服务器上向上向下测试。
逐级排查。
老男孩老师期待大家更多的思路和排查方法。

本文出自 “老男孩的linux博客” 博客,出处http://oldboy.blog.51cto.com/2561410/784625

【转读】如何运用责任激发员工的工作热情

2012年2月25日 没有评论

业员工的士气低落是最常遇到的问题,这也就是如何提高员工的工作热情的问题,针对这个问题企业主管们常用的方法是激励与考核。企业有大有小,解决 问题的方法也有所差异。小企业其实可以叫老板参与到里面来,有时候老板的一个表情、一句话、一个动作、一件小事就可以达到提升员工士气的目的。但一个有规 模的企业呢?我今日想谈得是,一个企业应以责任来激励激发员工的工作热情。

一个人的工作业绩与其工作动机被激发的程度直接相关,作为企业主管,在赋予下属责任时要层层都有激励点、检查下属责任时步步都给新激励、追究下属责任时处处都留暗激励。

在企业的运作过程中,不仅能力相同的人常常会做出不同的成绩,而且能力差的人往往还可能比能力强的人工作得更好。为什么呢?这里就有一个企业领导 者、管理者对下属的责任激励的问题。行为科学告诉我们,一个人的工作业绩不仅取决于他的工作能力,而且要看他的工作动机被激发的程度。在诸多的激励举措 中,责任激励对激发人的工作热情更为有效。因此,企业主管如果能恰到好处地运用责任激励艺术,往往就会收到意想不到的激励效果。

一、赋予下属责任要层层都有激励点

我们的企业主管,相当多的只知道给下属交代责任,要求下属必须怎么样,却很少考虑自己应怎样赋予下属责任,怎样融激励于责任。这也是我们目前许多企业内部潜能难以开发,员工的创新力难以激发的一个极为重要的原因。

1、赋予下属责任,要善于把握时机,把交代责任作为实施责任激励的起点。

作为主管,在统筹企业全局的前提下,一个基本的职责就是通过科学合理地分解责任将企业工作目标落实到岗、交代到人。向下属交代责任,不要过于草率、 随便,要善于把握时机。如果你赋予责任的当事人是参与某项工作目标的制定人,目标一经确定,就应当着所有参与目标制定者的面立即交代责任;如果责任人不是 工作目标决策的参与者,你应根据工作目标的大小,及时地、慎重地选择诸如当面亲自交代责任、会上当众交代责任、与责任人签定责任书等某种形式,让责任人感 受到你对他的信任与重视,使其从担负责任的第一分钟起就受到激励。这里,“及时”二字非常重要。这不仅是一种工作作风、一种效率,更是你对责任人的一种重 视与信任。

2、交代责任内容,要善于鼓舞士气,在明晰责任的过程中鼓足下属的勇气。

企业中的每一个工作目标都是具体的,分解到每一个岗位、每一个责任人的责任也都是具体的。作为主管,在赋予下属责任的时候,一定要明晰责任的具体事 项,认真交代清楚责任内容。有些主管在这个工作层面上的认识往往有偏误,总以为只要把工作任务布置下去,下属应该知道责任,没有必要对责任内容作过多的强 调。其结果,一些下属往往会因责任界限不清而草率了事,更谈不上从中受到什么激励了。为此,你应把下属分内应做的事尽可能地讲清说细,伴随对具体责任要求 的表述,要注意对下属给予相应能力的肯定,以增添责任人履行责任的自信,从而鼓足工作的勇气。同时,你还应向下属交代清楚实现不了工作目标所要承担的责任 和追究的形式,给责任人必要的压力,迫使责任人不断提升工作的责任感。

3、陈述责任要点,要善于提升责任,以托负责任激发责任承担人的上进心。

企业主管是否能够善用责任激励,一个重要的标志就是你在交代责任的过程中是否善于运用语言的艺术性,适当地提升责任。比如,有意识地放慢说话的速 度,运用气平声沉的谈话语气提升责任,增加谈话的严肃性,使对方感受到你所言之重要,从而认真掂量其所担职责之分量。再比如,谈话中注意运用理性分析来提 升责任,深刻阐述责任人所负之责对组织、对全局的影响和意义,让对方产生深受信任和被你所器重之感。这里的关键是“信任”,“用人不疑,疑人不用”,既然 你赋予他责任,最基本的就是要“信任”。信任既是对人的价值的一种肯定,也是一种奖赏。责任人在得到充分信任后,便会产生荣誉感,激发责任感,增强事业 感。从而迸发出更大的积极性和创造性。

二、检查下属责任要步步都给新激励

作为主管,在分解工作目标,责任到岗到人之后,你的任务不仅是要有步骤、有目的地检查责任的落实情况,还要善于把检查、督促的过程变成“二次激励”的过程。

1、提供一个机会,在激励中检查下属的责任计划。

在下属进入责任岗位之前,作为主管要善于引导下属围绕工作目标进行全面思考,让下属把准工作目标,明了所负责任的意义,理清工作的思路。可找其进行 个别交谈,一方面了解责任人对责任的理解程度、对承担该责任的真实态度以及基本的工作思路,以便及时发现问题,当即作出进一步的激励性引导,使其工作计划 更趋完善;另一方面也为你以后检查他的责任落实情况作了进一步的思想准备。还可以召开一定范围的誓师动员大会,为责任人提供一个表态发言的机会,在促使其 提高认识、理清思路的基础上当众作出承诺,“言必信,行必果”,这种承诺对责任人本身来说,无疑就是一种巨大的自我激励。

2、施加一定压力,在鞭策中督促下属的责任进度。

要明确告诉责任人,你将组织人员定期对其责任的落实情况和项目的进展情况进行必要的检查。你要注意的是:①要按预先所定的时间进行检查,以便责任人 将总体目标分解为阶段性目标,并合理安排好阶段性工作。②检查工作要注重科学性,要运用定性与定量相结合的检查手段,确保检查结果的说服力。③要及时将检 查结果与责任人进行沟通,使其对自己的工作做到心中有数,以便进一步安排好下步工作。这样做,具有三大激励作用:—是可以通过对下属实施超前压力,使其从 进入岗位之初就有一种将要接受检查的心理准备,心态上的紧迫感和责任感会使其时时处于激奋的状态,在这种激奋的状态下往往就能创造出“奇迹”。二是阶段性 的责任检查可以使责任人因倍受压力而加大努力程度,及时扭转不利局面。三是如果检查结果优良,则会使责任人深受鼓舞,增添下一阶段工作“更上一层楼”的勇 气。

3、授予一定权限,在关怀中激发下属的责任热情。

责任与权力总是相伴而行的。你赋予下属责任的过程,其实也是授予下属权力的过程。一个善于分解责任的主管,也一定是乐于并善于授权的主管。在这样的 主管旗下,人人都有参与企业各种事务的机会,都有自己的用武之地。对于已经被赋予责任的下属来说,承担责任本身就是一种挑战,尤其是处于如此机会均等的竞 争氛围里,担负责任唯有奋发向上,别无其它选择。当你阶段性地检查其工作的时候,一旦查出下属在岗位中存在某些问题,除非是渎职所致,一般不要急于追究责 任,应本着引导的原则,耐心帮助下属找出存在问题的原因和解决问题的办法。领导对下属的最大关怀莫过于工作上的支持,这种支持所带来的激励远远超过其他的 关怀。当领导帮助下属解决问题时,就会使下属在体会到倍受关怀和温暖的同时,也产生强烈的自愧感。由此会激发下属产生“不干出个样子无颜面对江东父老”的 信心,从而焕发出高昂的责任热情。

三、追究下属责任要处处都留暗激励

作为主管,从企业管理的基本要求出发,如果下属在规定的时限内没有能如期完成工作目标,不论其原因是什么,都应追究其相应责任。既是追究责任,就免 不了有种种形式的惩戒,工作稍不注意,下属的积极性就会受挫。这就要求我们的主管,即使是在追究下属责任的时候,也不能忽略激发员工的积极性这一工作主 题,应在分析造成履行责任不力的原因基础上,根据责任的大小,区别情况采用不同的追究形式,并尽可能融暗激励于追究,力求使追究的下属少受一点挫折,多得 一分鼓励。

1、自揽责任作表率,引导下属自纠其错。

不论造成下属履行职责不力的具体原因是什么,只要下属失职,企业主管作为赋责授权者,理应主动承担领导责任。这并不仅仅是一种姿态,事实上,任何下 属的失职,在某种意义上都有你用人不当、检查不严或监督不力的因素在内。领导责任自究也要讲究方式方法,要在尽可能多的场合表达自责,尤其不要忘了面对失 职的下属亲自说一句:“这里有我的责任”,这是领导者人格完善的一种体现,也是帮助下属“发扬成绩,纠正错误,以利再战”的有效武器。领导责任自究对增强 下属承担责任的主动性、引导下属自纠其错无疑会起到极大的激励作用。

2、曲径通幽多“私了”,暗示“士为知已者死”。

对于有些工作确实尽了努力,但是由于种种难以抗拒的客观因素所致,或受本人的能力所限而履行责任不力的下属,适合采用暗追究的方式,在让本人明白其 所造成的工作失职的利害关系的前提下,引导其体面地主动辞职让位,到其它更为适合的岗位上去工作。这样做,会使下属在人前保留一份自尊,也多了许多重新振 作的机会。你的这番苦心,足以令其在经受了积极的心理体验后,在今后的工作中有所表现。

3、大是大非不含糊,“杀一儆百”警示众属。

对于因工作玩忽职守、人为因素造成的履行责任不力的责任人,或虽其它因素所致但造成重大损失的责任人,应在公开场合大张旗鼓地“清算”其失职的责 任,宣布惩处的决定。此举的目的与其说是在惩处责任人,到不如说是在告诫所有部属。你在大是大非面前的这种原则性,对每一个部属都是一种暗激励。当然,开 诚布公地惩处,必须有理有据,要让失责者和所有的部属都口服心服,只有这样,才能受到警示众属的效果。

下面是××公司企业HR部门拟定,提交老总批阅的文件,归纳为《激励八法二十则》

一、使命法

1.自我激励
A.方法:
激励斗志的方法可以多种多样。如:由公司老总或其他事业有成的人士讲解创业经历,让员工认识到事业的可能性和艰难性;邀请成功学方面的专家到公司讲课;订购成功学方面的书刊给员工阅读让员工讲出自己心中的理想以及实现理想的打算等。
B.原理:
每个人都有自己的梦想,都渴望成功,都希望过上美好的生活。当员工心中被尘封已久的理想再次被点燃时,他们会表现出很大的爆发力。而他们心里明白,要成功就必须从做好手头上的工作开始。

2.个人业务承诺计划
A.方法:
让每名员工年初制定本人全年业务计划,向公司立下“军令状”。由其直接主管负责考察业绩完成情况、执行力度、团队力度及团队精神,并予以必要的指导、协助和鼓励。但不要给员工制定太多的目标,而要鼓励他们充分发挥潜能和创造性。
B.原理:
根据期望几率理论,一个人从事某项活动的动力或激励力的大小,取决于该项活动产生成果的吸引力和该项成果实现几率的大小。完全的目标导向一步步完成使他们充满成就感,团队的支持让他们感受到动力和宽慰。

3.组建临时团队
A.方法:
将某个重要的业务计划或项目由一个临时组建的团队去做。
B.原理:
临时团队之所以可以产生较高的工作效率,其组织形式对成员的激励功不可没。临时小组有以下的特点:人少(最佳规模为3-7人),志愿组成,目标导向,通常 完成任务之后自行解散。适当的、具有一定挑战性可又有可能达成的目标能很好地激发临时团队成员的创新激情,同时临时团队实行自我管理,即团队成员从本来的 被控制变成具有一定决策权。当一个人充满责任感的时候,他将会全身心地投入进去。

二、生存法

4.生存竞争
A.方法:
对员工进行动态评估,让每个人都知道自己所处的位置。
B.原理:
让员工明白,如果他们不努力工作或者工作没有业绩的话,就有可能被公司淘汰出局。在生存竞争常激烈的现代社会,可能失去饭碗的压力将会极大地激发员工的工作热情。
C.范例:
美国通用电气将其所有的员工分为五类。第一类是顶尖的人才,占10%;次一些的是第二类,占15%;第三类是中等水平的员工,占50%,他们的变动弹性最 大,他们有机会选择何去何从;接下来是占15%的第四类,需要对他敲响警钟,督促他们上进;第五类是最差的,占10%,只能毫不留情地辞退他们。这种淘汰 机制给了员工充分的紧迫感,也给了他们充足的动力。

三、竞争

5.新陈代谢机制
A.方法:
制定公司、部门及个人工作目标,建立相应的考核机制,达不到目标的责任人员,无论级别、资历、以往贡献都得下台。
B.原理:
许多公司的业务计划在制定时意气风发,可是在执行过程中却因种种原因不断打折扣,最后即使完不成也不了了之,使得制定业务计划本身已经失去意义,领导丧失权威,员工丧失紧迫感和责任感。

6.分组竞争机制
A.方法:
将公司业务部门划分为若干小组,每天(周)公布业绩排行榜,月终总结,奖励先进,激励后进。
B.原理:
最好的机制不是试图去“让懒人变得有生产力”,而是在企业中形成高绩效的环境,使员工的敬业精神得以发扬光大,让懒惰者无处藏身。基于真诚合作和责任承诺之上的内部竞争,来自同级的压力比来自上级的命令更能促进员工的积极性和工作热情。

7.在内部引入外来竞争
A.方法:
允许内部机构向外界采购产品或服务,使内部相关的供应部门不能再依靠独家生意,舒舒服服过日子而不思进取。
B.原则:
“铁饭碗”变成“泥饭碗”。内部机构不努力就会没饭吃,当然会加倍努力改善产品或服务质量,并努力降低成本以增强竞争力。

四、兴趣法

8.鼓励“非法行动”
A.方法:
允许和鼓励员工做一些正常工作、常规程序以外的尝试。
B.原理:
很多时候,员工在工作中的新想法、新创意是突如其来的,但是这一部分计划外的想法却同很多计划的想法同样具有价值,需要被企业重视并予以支持。有些耗资不 多的新构思,技术人员可以通过自己的简单试验来测试。类似情况经常发生在企业的基层,基层员工常常是最了解产品、客户和市场的,他们由于成年累月的实际操 作,对这些方面有独到的了解,知道怎样提高生产和市场拓展效率。
C.范例:
通用电器公司的巨大成功,例如在工业塑料和飞机发动机的成功,就是“非法活动”的直接结果。IBM甚至在管理制度上故意设计得有一点“漏洞”,以便让一些人在预算之外做点事,执行计划以外的计划。在25年中,IBM重要产品的生产没有任何一项是该公司的正式系统搞出来的。

9.给员工完全自由发挥的空间
A.方法:
如对公司科研人员而言,可以允许其花费公司时间的15%,在自己选定的领域内从事研究和发明创造活动。
B.原理:
兴趣是最好的老师,也是最好的工作推进剂。员工只有对自己所从事的工作真正感兴趣,能从中获得快乐,才会竭尽全力把工作做好。

五、空间

10.培训机会
A.方法:
为员工提供全方位、多层次的培训机会,增加企业人力资源的价值和员工自身的价值。
B.原理:
在知识更新越来越快的信息时代,“终身学习”和“建立学习型组织”已成为个人与企业在激烈竞争中立于不败之地的基本要求。企业应该通过培训开发来挖掘员工潜力,实现员工人力资源的保值增值。这既是调动员工积极性的需要,也是维护和提高企业市场竞争力极为重要的一环。

11.岗位轮换
A.方法:
员工定期(比如一年)轮岗,尝试不同的工作岗位。
B.原理:
在传统管理时代,强调组织分工明确,结果员工每天重复单调的工作,虽然在一定程度上提高了生产率,但成员的满意度下降。人本思想问世后,对人的激励有了新 的认识,开始注意完善人的能力,开发人的潜力,并在此基础上健全岗位轮换制度,使员工能更加充分、主动地选择具有挑战性的工作,从而使工作内容横向丰富化 和纵向扩大化。这样,工作产生的乐趣和挑战性就成为了工作本身对员工的回报。

12.给予员工顺畅的事业发展渠道
A.方法:
在干部选拔上,企业要给员工更多的机会,从以前对外聘用为主,转变为对外聘用与内部选拔并重,最后过渡到内部培养选拔为主,变“伯乐相马”为“在赛马中选马”。
B.原理:
事业发展是员工内在报酬体系的重要组成部分。依据马斯洛的需要层次理论,自我实现是人最高层次的需要。职业发展属于满足人的自我实现需要的范畴,因而会产生更大的激励作用。

13.减少审批程序
A.方法:
减少一个产品研发或市场拓展计划的审批程序和时间,不要设置过高的审查标准,应留给相关人员更多的空间。
B.原理:
复杂性引发冷漠及惰性。如果业务人员的一项雄心勃勃的拓展计划面临公司的层层把关,他自然会降低工作的热情。而事实上很多划时代的产品或营销方案只是出于一个看似荒谬的点子。

14.员工参与决策
A.方法:
建立员工参与管理、提出合理化建议的机制,提高员工主人翁参与意识。如让员工参与公司发展目标、方向的分析研讨,让员工参与项目确定,参与保证公司正常运转的各项规章制度的制定。
B.原理:
没有人喜欢别人强加于自已身上的东西。但如果让员工参与公司经营目标、管理制度等的制定,他们就会觉得那就是自己的目标和行为规则,就会充满期待地投入工作。

六、荣誉法

15.荣誉激励
A.方法:
对有突出表现或贡献的员工,对长期以来一直在为公司奉献的员工,毫不吝啬地授予一些头衔、荣誉,换来员工的认同感,从而激励员工的干劲。
B.原理:
每个人都对归属感及成就感充满渴望,都希望自己的工作有意义,荣誉从来都是人们激情的催化剂。拿破仑“为法兰西而战”的名句更是使他的军队所向披靡。
C.范例:
IBM公司有一个“百分之百俱乐部”,当公司员工完成他的年度任务,他就被批准为该俱乐部会员,他和他的家人被邀请参加隆重的集会。结果,公司的雇员都将获得“百分之百俱乐部”会员资格作为第一目标,以获取那份光荣。

七、危机

16.危机教育
A.方法:
不断地向员工灌输危机观念,让他们明白企业生存环境的艰难,以及由此可能对他们的工作、生活带来的不利影响。
B.原理:
企业发展的道路充满危机。正是因为如此,盖茨才会不断地告诫他的员工微软永远离破产只有18个月!任正非才会警告:华为的冬天很快就要来临!然而这种危机 往往并不是所有员工都能感受到的,特别是非市场一线人员。因此有必要不断向员工灌输危机观念,树立危机意识,重燃员工的创业激情。

八、沟通

17.双向沟通
A.方法:
基层员工与高层管理人员恳谈会、经理接待日、员工意见调查、总裁信箱、设立申诉制度,让任何的意见和不满得到及时、有效的表达;建立信息发布会、发布栏、企业内部刊物等,让员工及时了解企业动向、动态,增强他们参与的积极性。
B.原理:
使员工感受到自己受重视、有存在价值,自然会有热情去为公司做事。

18.变惩罚为激励
A.方法:
员工犯错误,通过管理者与其进行朋友式的沟通和交流,让员工感受到被尊重和爱护,从而主动承认错误,主动接受惩罚,主动改善工作质量。
B.原理:
对员工犯的错误,企业普遍的做法就是严厉批评和惩罚!然而处罚并不能真正解决问题,反而会造成员工积怨甚至流失。只有沟通才能取得事半功倍的效果。

19.亲情关怀
A.方法:
企业的经理和主管应该是一个细心的人。对员工的工作成绩,哪怕是很小的贡献也及时给予回馈。一张小纸条,一个电话留言,一封E-mail,一个两张电影票的红包,都能让员工感到自己受领导关注、工作被认可,并为此而兴奋不已。
此外还有建立员工生日情况表,总经理签发员工生日贺卡,关心和慰问有困难员工等,可以很好地增强员工的归属感。
B.原理:
任何人都希望自己努力的成果能被认可、赞同和感激,这是人们前进的动力。

20.变消极管理为积极管理
A.方法:
管理者对员工给予积极意见而不是责备。
B.原理:
员工往往只体验到“因犯错而做出的管理(消极管理)”,亦即上司大多是在认为他们犯错误而须加以纠正时才给予意见。如果员工觉得他们的决定普遍获得支持, 并在真正犯错时会获得适当指导,他们便会更为积极进取而充满自信,并愿意承担职责和做出决定。如果员工清楚知道上司对他们的期望,知道自己受到重视和信 任,并会获得鼓励和激励,他们便会全力以赴,尽心工作。

来源:草根网(www.20ju.com) – 互联网界的读者文摘

分类: 观念思维 标签:

【转】Linux运维常用的免费的开源软件

2012年2月19日 没有评论

操作系统:Centos※,Freebsd,Ubuntu
网站服务:apache※,nginx※,lighttpd,php※,tomcat※,resin※
数据  库:Mysql※,PostgreSQL,Mysql-proxy
代理相关:lvs,keepalived,haproxy,nginx,apache,heartbeat(此行都是※)
网站缓存:squid※,nginx※,varnish
内存缓存:memcache※,memcached,TokyoTyrant※,MongoDB,Cassandra※,redis※,tair,CouchDB
存储相关:Nfs※,Moosefs※,Hadoop※,gfs※,lustre,FastDFS
版本管理:cvs,svn※,git※
监控报警:mboy,mrtg,nagios※,cacti※,zbbix,munin※,hyperic※
域名解析:bind※,powerdns,dnsmq※
同步软件:rsync,sersync,drbd,csync2+lsyncd(此行都是※)
分发工具:Secboy※,expect※,puppet※,cfengine※,ssh+rsync+sersync※
虚拟软件:xen※,kvm
内网软件:iptables※,zebra※,iftraf,ntop※,tc※,iftop
邮件软件:qmail※,posfix※,sendmail
远程拨号:openvpn※,pptp,openswan※,ipip※
统一认证:ldap※
队列工具:ActiveMQ※,RabbitMQ
打包发布:mvn※,ants※,jenkins※
测试软件:apache ab,smokeping,siege,JMeter,Webbench,LoadRunner(此行都是※)
日志相关:syslog,rsyslog,Awstats

提示:
1)以上所有软件都是老男孩用过或测试过的。
2)带的为老男孩最近几年用的比较多,可信任使用的。也是近年来linux运维的大众。
3)有了功能分类和软件名,大家有需求,可以按功能找软件直接G就知道了。
4) 学习要有舍有得,什么都抓必然短时间都不会精,希望大家能抓重点,抓精髓,大众软件(带※)先熟练了,这是基础加提高,在研究小众软件(不带※),这是高手之路,最后在研究偏门的,世外高手之路,当然前提是先掌握前面的大众和小众。
5)当然还有一些没有大众开源的有一些也很棒,如审计堡垒机程序。

来源:http://oldboy.blog.51cto.com/2561410/775056