SoapClient ExecuteQuery第二次执行失败问题求助
I’ve seen this exact pattern with SoapClient before—first call works fine, second call blows up with memory errors and a "no XML document" fault, and a provision action resets things temporarily. Here’s how to troubleshoot and fix it:
Possible Fixes & Debugging Steps
1. Recreate the SoapClient Instance for Each Call
Instead of reusing a single SoapClient object across multiple calls, instantiate a new one every time. This ensures any stuck resources (like open connections or buffered data) from the first call get properly cleaned up by PHP’s garbage collector.
Example code:
function makeSoapCall($language) { // Set configs inside the function to ensure fresh state ini_set('memory_limit','1024M'); ini_set('soap.wsdl_cache_enabled', 0); ini_set('soap.wsdl_cache_ttl', 0); // Create a new client every time $client = new SoapClient('your_wsdl_url_here'); $xmlQuery = '<Query> <Select languages="'.$language.'"> <Feature ... </Feature></Select></Query>'; $response = $client->__call('your_target_method', [$xmlQuery]); // Explicitly clean up unset($client); gc_collect_cycles(); // Force garbage collection to free memory return $response; } // Call it twice without issues makeSoapCall('en'); makeSoapCall('fr');
2. Debug the Raw Response to Validate XML
The "looks like we got no XML document" error usually means the second call is receiving a non-XML response (like an error page, empty string, or corrupted data). Enable tracing on the SoapClient to see exactly what’s being sent and received:
$client = new SoapClient('your_wsdl_url_here', ['trace' => 1]); try { $response = $client->__call('your_target_method', [$xmlQuery]); } catch (SoapFault $e) { // Print raw request/response to diagnose echo "Request: " . $client->__getLastRequest() . "\n"; echo "Response: " . $client->__getLastResponse() . "\n"; echo "Error Message: " . $e->getMessage(); }
If the second response is empty or shows a server error (like 500 Internal Server Error), the problem is likely server-side—your first call is leaving the server in a broken state until the provision action resets it.
3. Replicate the "Provision" Action Programmatically
Since running the provision action fixes the issue once, figure out what that action does (e.g., resets a server-side session, clears a cache, reinitializes a service) and call it programmatically before each SoapClient request. This ensures the server starts in a clean state every time.
4. Check for Memory Leaks in Your Code
Even with memory_limit set to 1024M, if your code is holding onto large objects or responses in global variables, the second call could push memory usage over the limit. Use memory_get_usage() to track memory changes:
echo "Memory before call: " . memory_get_usage(true) . "\n"; $response = $client->__call('your_target_method', [$xmlQuery]); echo "Memory after call: " . memory_get_usage(true) . "\n"; unset($response); echo "Memory after cleanup: " . memory_get_usage(true) . "\n";
If memory doesn’t drop significantly after unsetting the response, you might have a memory leak in your code or the SoapClient extension itself.
Final Notes
The most likely fixes here are either recreating the SoapClient instance for each call (to fix client-side resource leaks) or replicating the provision action (to fix server-side state issues). Start with recreating the client—it’s the simplest and most common solution for this exact problem.
内容的提问来源于stack exchange,提问作者tryAndroid

