gpt4 book ai didi

在方法(类)中使用时,PHP 套接字绑定(bind)/监听不起作用

转载 作者:行者123 更新时间:2023-12-03 11:52:11 25 4
gpt4 key购买 nike

我想为少数 cron 作业实现一个简单的锁定机制,并决定以不同寻常的方式来实现。当涉及到套接字创建/绑定(bind)/监听时,PHP 似乎有点错误。

有效的代码:

<?php
echo 'EXECUTING: '. __METHOD__ . \PHP_EOL;

if(false === ($socket = \socket_create(\AF_INET, \SOCK_STREAM, \SOL_TCP))) {
die('create');
}

if(false === ($bind = \socket_bind($socket, '127.0.0.1', 4444))) {
die('bind');
}

if(false === ($listen = \socket_listen($socket))) {
die('listen');
}

var_dump($socket, $bind, $listen);

这将创建一个套接字,将其绑定(bind)到接口(interface)等待传入连接。
您可以通过调用来检查它:
netstat -anp | grep LIST | grep tcp

如果您采用相同的 PHP 代码并将其放入一个简单的类中,它将不会绑定(bind)/监听。这是我正在谈论的代码:
<?php

class Test
{
public function lock()
{
echo 'EXECUTING: '. __METHOD__ . \PHP_EOL;

if(false === ($socket = \socket_create(\AF_INET, \SOCK_STREAM, \SOL_TCP))) {
die('create');
}

if(false === ($bind = \socket_bind($socket, '127.0.0.1', 4444))) {
die('bind');
}

if(false === ($listen = \socket_listen($socket))) {
die('listen');
}

var_dump($socket, $bind, $listen);
}
}

$t = new Test();
$t->lock();

echo 'Working...'. \PHP_EOL;
sleep(60);
echo 'Done.';

执行这段代码,你会看到 var_dump 会这样说:
  • $socket是一种资源(这是我们想要的)
  • $bind = true
  • $listen = true

  • 但代码实际上没有绑定(bind)/监听。

    我做错了什么?

    编辑:

    测试:
  • PHP 5.4.4 (Linux)
  • PHP 5.3.3 (Linux)
  • 最佳答案

    答案很简单:您的 $socket variable 是一个局部变量,它没有引用,而是在方法范围内。这意味着,一旦方法被执行,PHP 将销毁所有局部变量 - 所以 $socket也是。 IE。您正在成功创建套接字,然后 PHP 在同一时刻取消设置它(因为方法结束了它的执行)。请注意,取消设置局部变量并不意味着立即释放内存。垃圾收集周期很昂贵,所以 PHP 只会在达到内存限制时才会这样做。

    要查看差异,请放置 sleep()在创建套接字后调用内部方法。 PHP 有 garbage collection从 5.3 版开始,因此您尝试过的版本会受到影响。想看直播,可以查看this snippet :

    class Foo
    {

    public function __destruct()
    {
    echo('destroyed'.PHP_EOL);
    }
    }

    class Bar
    {
    public function test()
    {
    echo('starting method'.PHP_EOL);
    $obj = new Foo();
    echo('ending method'.PHP_EOL);
    }
    }
    echo('start script'.PHP_EOL);
    $obj = new Bar;
    $obj->test();
    echo('end script'.PHP_EOL);

    结果

    启动脚本
    启动方式
    结束方式
    毁坏
    结束脚本

    - 如您所见,在退出方法调用后立即调用了类析构函数,因为本地 $obj变量在其他任何地方都没有引用。

    关于在方法(类)中使用时,PHP 套接字绑定(bind)/监听不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19743884/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com