zhidd
V2EX  ›  问与答

php 页面每次访问后,都会释放所有资源,也就是说,单例的写法,没什么意义,有人说 php 是页面级别,除了页面级别,单例写法没用

  •  
  •   zhidd · Mar 21, 2016 · 4567 views
    This topic created in 3744 days ago, the information mentioned may be changed or developed.
    比如说,前 10 秒,我访问 a.php,里面有个 static 的 mydql 链接,过了 10 秒,我又访问 a.php,,我是无办法使用上一次的 static 的 mysql 链接。看过 discuz 、 phpcms 的源码,都有工厂模式, new 出来的单例好像没什么意义,浪费内存
    11 replies    2016-03-23 10:50:19 +08:00
    ketle
        1
    ketle  
       Mar 21, 2016
    查 10 次 sql 就有用了
    zhidd
        2
    zhidd  
    OP
       Mar 21, 2016
    @ketle 你意思是一个页面级别,如果需要查 10 次 sql 就起作用了,
    mcfog
        3
    mcfog  
       Mar 21, 2016   ❤️ 1
    1. 既然单次页面访问后会释放,何来浪费内存一说?
    2. PHP 单例的作用随便列一列

    + 即使单例的生命周期只有一个请求内,照样能有很好的节省内存作用(比如 IP 库、拼音表之类的场景,单个实例很可能占用大量内存,一次请求很可能大量涉及调用,单例效果明显)
    + 同理,除了内存,还节省其它各种资源,比如 mysql 连接数, redis 连接数,句柄数等等,另外还节省初始化的开销
    + 单例伴随工厂,对代码可读性、可测试性等都是提升
    + 单例可以实现维护统一状态,比如说单例一个 mysql 连接,就可以在实例里维护 db 请求次数、总耗时什么的

    3. 最后, db 连接、 redis 连接之类的,往往还会通过“持久连接” persistent connection 实现跨请求的资源复用

    参考 http://php.net/manual/zh/pdo.connections.php#example-963
    zhidd
        4
    zhidd  
    OP
       Mar 21, 2016
    @mcfog mysql 的 persistent 连接,前 10 秒,我访问了 a.php 后,php-frm 模块会释放 persistent 连接,过了 10 秒,我又访问 a.php,它是重新 persistent connection ,而且 persistent connection 首次链接很耗时间,然而并没有卵用
    wesley
        5
    wesley  
       Mar 21, 2016
    @zhidd 试一下把 php-fpm 的最小进程数调大一点, 但不能大过 mysql 的最大连接数
    skydiver
        6
    skydiver  
       Mar 21, 2016
    @zhidd 持久连接可以跨请求保持的。如果你用的 php-fpm ,设置 pm.max_request = 500 ,那么 500 次请求才会重启一次 worker 进程,那么持久连接就可以 500 次请求里共用。
    mcfog
        7
    mcfog  
       Mar 21, 2016
    @zhidd

    是整个 PHP 社区出问题,弄一个没有实际作用的 feature 的可能性大?还是你自己配置、使用不当的可能性大?十秒内访问是否正常复用连接了?如果你觉得十秒就释放不合理,有没有找过哪里配置这个时间呢?

    以上。

    看轻别人觉得没意义然并卵是你的权利
    iyaozhen
        8
    iyaozhen  
       Mar 21, 2016   ❤️ 1
    web 开发的话你说的这种情形确实用处不大。但别的场景还是可以用的,比如一些复杂的脚本程序。目前来看 Nginx+PHP-FPM 的模式简单、高效、实用,基本的业务场景都能满足。

    还有持久连接在 PHP-FPM 模式下是不好使(个人拙见: https://iyaozhen.com/php-mysql_pconnect-discuss.html ),目前来看不建议使用持久连接,其实每次都开一个连接消耗也不是很大。
    spance
        9
    spance  
       Mar 21, 2016   ❤️ 1
    php 没有生命周期,像 java python ruby nodejs 。。。这些 web 应用结构上都有 application session page 等生命周期, php 这货只是一个进化版的 cgi 而以,遇请求则解析,没有生命没有周期。
    你说的这是数据库连接池, php 这种以 cgi 为底线的结构上是不可能存在的。于是别人在 web 容器的生命周期可以干的事情, php 要放到每一个页面响应中去完成。
    linpf
        10
    linpf  
       Mar 21, 2016
    可以用 php-cli 或者其他语言做个数据库连接池,守护进程运行,然后通过 socket 传递 mysql 请求与返回数据。
    hankwh
        11
    hankwh  
       Mar 23, 2016
    @mcfog 霸气~
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   3797 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 64ms · UTC 00:56 · PVG 08:56 · LAX 17:56 · JFK 20:56
    ♥ Do have faith in what you're doing.