Skip to content

SOAP HTTP socket not closing on object destruction #18990

Closed

Description

@Sn0wCrack

Description

This was originally reported this on the PHP bug tracker a few years ago: https://bugs.php.net/bug.php?id=81029

If a SoapClient object is constructed without specifying the 'keep_alive' option to false, the socket never appears to be closed if it falls out of scope

The provided script should be able to reproduce this, you can check the open sockets by running the script like: "php /path/to/script.php &" and using the resulting PID on lsof -a -p {pid}

You should slowly see a list of TCP connections slowly build up over time similar to this:

php     4396 vagrant    3u  IPv4  53416      0t0     TCP homestead:57814->ec2-52-7-155-169.compute-1.amazonaws.com:https (ESTABLISHED)
php     4396 vagrant    4u  IPv4  53447      0t0     TCP homestead:57816->ec2-52-7-155-169.compute-1.amazonaws.com:https (ESTABLISHED)
php     4396 vagrant    5u  IPv4  54451      0t0     TCP homestead:57818->ec2-52-7-155-169.compute-1.amazonaws.com:https (ESTABLISHED)

If instead you were to add ['keep_alive' => false] as the options parameter on the SoapClient you'll see that the TCP connections don't appear to build up.

While I do understand the purpose of Keep Alive to keep a single connection open, I would assume this is still a bug as the SoapClient has gone out of scope and new SoapClient objects don't appear to reuse the existing connection and simply ignore it creating a new one.

File descriptors increase with each iteration of the loop:

<?php

function call(int $number) {
    $client = new SoapClient('https://www.dataaccess.com/webservicesserver/NumberConversion.wso?WSDL');
    $response = $client->NumberToWords(['ubiNum' => $number]);
    return $response->NumberToWordsResult;
}

$numbers = array_fill(0, 10000, 1);

foreach ($numbers as $number) {
    call($number);
}

No increase in open file descriptors:

<?php


function call(int $number) {
    $client = new SoapClient('https://www.dataaccess.com/webservicesserver/NumberConversion.wso?WSDL', ['keep_alive' => false]);
    $response = $client->NumberToWords(['ubiNum' => $number]);
    return $response->NumberToWordsResult;
}

$numbers = array_fill(0, 10000, 1);

foreach ($numbers as $number) {
    call($number);
}

PHP Version

Originally replicated on PHP 7.4.19.

This has been anecdotally observed on PHP 8.0-8.3 as well.

Operating System

macOS, Ubuntu 24.04 and RHEL7/8/9

Activity

  1. ndossche commented on Jul 1, 2025

    @ndossche
    Member

    I think you're right.
    I think the culprit is this line:

    GC_ADDREF(stream->res);

    But I would need to double check after work.

  2. self-assigned this
    on Jul 1, 2025
  3. added a commit that references this issue on Jul 1, 2025
    893ddd7
  4. added 2 commits that reference this issue on Jul 2, 2025
    69328ba
    764154d
  5. added a commit that references this issue on Jul 2, 2025
    51149b6
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions