如题:
php中的static除了能不实例化访问还有什么用?
目前感觉php中的static方法和属性,作用貌似只有不实例化访问;而且大家一直说的static只占用一份内存有多大作用?因为php多是多进程方式运行的,而且据说进程间是不共享资源的,也就是说多个用户同时访问时,static方法和类仍然有多份,无法实现共享,除非在一次请求中用到多次某个方法和属性,这是static才发挥了只占用一份内存的作用。
还有,php的单例模式有什么用?
如果多进程间不共享资源,那php的单例模式其实也没什么用了,比如想用单例模式来控制对数据库的访问,如果并发10个,那么也就是开了10个进程,10个进程又分别实例化了10个单例对象,那单例岂不是就失效了吗?
最近想深入钻研下php,也不知道该如何开始,很多书都是php的简单入门,越学越觉得自己懂得少了,请大牛或版主帮忙解释下以上的问题吧,多谢。

解决方案 »

  1.   

    比如这个图片中的题,当然只是实现结果,几行代码就能搞定。但来个get_value(80,60)试试,就应该需要很久,甚至死机。你就会想到,我用缓存、全局变量等。
    以下是我今天写的例子,希望对你有启发。
    /**
 * author Winter
 * 2016-11-22
 * PHP的单例模式
 * 模拟Java Bean
 * Class Php_bean
 */
class Php_bean{
    private static $_instance = null;
    private function __construct(){}
    private $hit = 0;//命中次数
    private $array = array();//缓存
    private $itratorCount = 0;//迭代次数
    public function add_itratorCount(){
        $this->itratorCount ++;
    }
    public function get_itratorCount(){
        return $this->itratorCount;
    }
    public function set_cache($row,$col,$value){
        $this->array[$row."_".$col] = $value;
    }
    public function get_cache($row,$col){
        if(isset($this->array[$row."_".$col])){
            return $this->array[$row."_".$col];
        }else{
            return false;
        }
    }
    public function add_hit(){
        $this->hit ++;
    }
    public function get_hit(){
        return $this->hit;
    }
    public static function instance(){
        if(self::$_instance instanceof self) return self::$_instance;
        self::$_instance =  new self;
        return self::$_instance;
    }
}

/**
     * author Winter
 * 2016-11-22
 * @param $row 行
 * @param $col 列
 * @return int
 */
function get_value($row,$col){
    $php_bean = Php_bean::instance();
    $php_bean->add_itratorCount();
    if($col > $row) return 0;
    if($row <=0) return 0;
    if($col == $row) return 1;
    if($row == 1) return 1;
    if($col == 1) return 1;
    $pre = $php_bean->get_cache($row-1,$col-1);
    $next = $php_bean->get_cache($row-1,$col-0);
    if($pre === false){
        $pre = get_value($row-1,$col-1);
        $php_bean->set_cache($row-1,$col-1,$pre);
    }else{
        $php_bean->add_hit();
    }
    if($next === false){
        $next = get_value($row-1,$col-0);
        $php_bean->set_cache($row-1,$col-0,$next);
    }else{
        $php_bean->add_hit();
    }
    $value =  $pre + $next;

    return $value;
}

$v = get_value(66,6);
var_dump($v);
$php_bean_obj = Php_bean::instance();
echo "hit:".$php_bean_obj->get_hit()."<br/>";
echo "itratorCount:".$php_bean_obj->get_itratorCount()."<br/>";
      

  2.   

    确实是,但是在一般的网络服务中,这种应用应该很少吧,刨去这种特例,static是不是就没有什么实际意义了,又或者说在多线程的php模式下static才能发挥更大的作用?
      

  3.   

    确实是,但是在一般的网络服务中,这种应用应该很少吧,刨去这种特例,static是不是就没有什么实际意义了,又或者说在多线程的php模式下static才能发挥更大的作用?这个例子在实际业务中也会经常遇到,其实就是性能问题,一个用户请求过来需要好几秒,服务器也扛不了多少并发。还有比如我用的redis时,有个模型专操作redis,业务关系我需要有很多key和很多类型。那我在这个模型里就用redis命名所有的key而且只在这个模型里有redis key,这样我很方便管理,必须回收无用的数据。提供测试时可以直接调用,在同一请求里已经格式化好的key不会乱,不需要每次格式化(比如每个key里都是有时期或其他可变字符串)
      

  4.   

    确实是,但是在一般的网络服务中,这种应用应该很少吧,刨去这种特例,static是不是就没有什么实际意义了,又或者说在多线程的php模式下static才能发挥更大的作用?这个例子在实际业务中也会经常遇到,其实就是性能问题,一个用户请求过来需要好几秒,服务器也扛不了多少并发。还有比如我用的redis时,有个模型专操作redis,业务关系我需要有很多key和很多类型。那我在这个模型里就用redis命名所有的key而且只在这个模型里有redis key,这样我很方便管理,必须回收无用的数据。提供测试时可以直接调用,在同一请求里已经格式化好的key不会乱,不需要每次格式化(比如每个key里都是有时期或其他可变字符串)你老盯着这个例子都说了服务中这种比较少了
      

  5.   

    静态类方法
    只被初始化一次,当程序执行离开此作用域时,其值不会消失,会使用上次执行的结果。
    声明类成员或方法为 static ,就可以不实例化类而直接访问,不能通过一个对象来访问其中的静态成员(静态方法除外)。静态成员属于类,不属于任何对象实例,但类的对象实例都能共享。
      

  6.   

    也就是说php的static只是在一次访问中有效,另一个访问来了,开启新的进程,最后仍然是有多少个进程就有多少份static的内存空间,因为进程间资源不能共享,对吧。那static的用途我觉得应该主要是在一次程序访问中,有多次用到某个成员或者方法的时候能发挥一些作用。
      

  7.   

    那意思还是我题目的意思?等架构复杂起来才能体会到好处?简单架构中static没有太实质的作用?
      

  8.   

    静态是相对同一程序而言的类的静态属性和方法只是使用范围受限的全局变量和函数
    这是纯面向对象编程带来的垃圾产物,应尽量避免使用真正的 static 变量,在编程中还是很有意义的
    比如一个开关函数function pingpong() {
      static $v = false;
      return $v = !$v;
    }
    就可使控制流变得很简洁
      

  9.   

    用到的地方还是很多的。比如做安全防范的时候,进行sql注入过滤,xss过滤和csrf过滤,将其统一封装成一个Security类,里面的方法就需要用到static来修饰,不然难道每一次过滤都要实例化一次吗?再开一个堆内存空间?类似的还有语言包、缓存等等。你用不到或者说是你体会不到,确实是你的项目架构过于简单。
      

  10.   

    静态类方法
    只被初始化一次,当程序执行离开此作用域时,其值不会消失,会使用上次执行的结果。
    声明类成员或方法为 static ,就可以不实例化类而直接访问,不能通过一个对象来访问其中的静态成员(静态方法除外)。静态成员属于类,不属于任何对象实例,但类的对象实例都能共享。