I am trying to debug a Laravel artisan command, executed via CLI, which in turn calls an external endpoint (via Guzzle).
Both the original app and the external endpoint are available locally, open in PHPStorm as two separate projects.
I'm able to debug the CLI command by running this command in terminal:
export XDEBUG_CONFIG="remote_enable=1 remote_mode=req remote_port=9000 remote_host=127.0.0.1 remote_connect_back=0"
(or for windows):
set XDEBUG_CONFIG="remote_enable=1 remote_mode=req remote_port=9000 remote_host=127.0.0.1 remote_connect_back=0"
As illustrated on PHPStorm docs, you can execute an external script by passing a debug query string:
$debuggingQuerystring = '';
if (isset($_GET['XDEBUG_SESSION_START'])) { // xdebug
$debuggingQuerystring = 'XDEBUG_SESSION_START=' . $_GET['XDEBUG_SESSION_START'];
}
if (isset($_COOKIE['XDEBUG_SESSION'])) { // xdebug (cookie)
$debuggingQuerystring = 'XDEBUG_SESSION_START=PHPSTORM';
}
if (isset($_GET['start_debug'])) { // zend debugger
$debuggingQuerystring = 'start_debug=' . $_GET['start_debug'];
}
$personJson = file_get_contents('http://127.0.0.1:778/backend.php?' . $debuggingQuerystring);
The current problem that when executed via CLI, the $debugQueryString is empty. What do we pass along and how to the external url which will allow debugging on the second project?
$client = new Guzzle\Http\Client($this->webhook_url);
$response = $client->post('', [], $this->params)->send();
$code = $response->getStatusCode();
This was easier than I thought.
$debuggingQuerystring = '';
if (isset($_GET['XDEBUG_SESSION_START'])) { // xdebug
$debuggingQuerystring = 'XDEBUG_SESSION_START=' . $_GET['XDEBUG_SESSION_START'];
}
if (isset($_COOKIE['XDEBUG_SESSION'])) { // xdebug (cookie)
$debuggingQuerystring = 'XDEBUG_SESSION_START=PHPSTORM';
}
if (isset($_GET['start_debug'])) { // zend debugger
$debuggingQuerystring = 'start_debug=' . $_GET['start_debug'];
}
if(empty($debuggingQuerystring))
{
$debuggingQuerystring = 'XDEBUG_SESSION_START=PHPSTORM';
}
$this->debugString = $debuggingQuerystring;
And then the url call:
$client = new Guzzle\Http\Client($this->webhook_url);
$response = $client->post('?' . $this->debugString, [], $this->final_data)->send();
$code = $response->getStatusCode();
Related
I use Node.js to run STOMP over WebSocket because it supports custom headers. When HTTP handshake, the server needs a cookie to check auth, not the token in the address.
As PHPer, I want to use this in PHP, but search google for a long time and found no way. can anyone help?
STOMP is not limited to Node.js, or Java, etc. There are
a STOMP PECL extension for PHP,
PHP STOMP libraries, e.g Stomp-PHP,
and general messaging libraries that support STOMP,
e.g. Enqueue's STOMP transport layer, or Laravel-Queue
Regarding your specific scenario, it's hard to come up with a straight-up answer without knowing more details but here is an example from the stomp-php library samples hat sets a custom header:
use Stomp\Client;
use Stomp\SimpleStomp;
use Stomp\Transport\Map;
// make a connection
$client = new Client('tcp://localhost:61613');
$stomp = new SimpleStomp($client);
// send a message to the queue
$body = array('city' => 'Belgrade', 'name' => 'Dejan');
$header = array();
$header['transformation'] = 'jms-map-json';
$mapMessage = new Map($body, $header);
$client->send('/queue/test', $mapMessage);
echo 'Sending array: ';
print_r($body);
$stomp->subscribe('/queue/test', 'transform-test', 'client', null, ['transformation' => 'jms-map-json']);
/** #var Map $msg */
$msg = $stomp->read();
// extract
if ($msg != null) {
echo 'Received array: ';
print_r($msg->map);
// mark the message as received in the queue
$stomp->ack($msg);
} else {
echo "Failed to receive a message\n";
}
you need a websocket stream wrapper if you want to connect using a protocol
You can use php-stomp-frame
https://github.com/jeeinn/php-stomp-frame
composer require jeeinn/php-stomp-frame
public function getStompMessage(): array
{
$stompFrame = new Frame();
$connectFrame = $stompFrame->setLogin($this->ss['login'], $this->ss['password'])
->setHeartBeat(0, 10000)->getConnect();
$subscribeFrame = $stompFrame->getSubscribe($this->ss['queue']);
$client = new Client($this->ss['host']);
$client->text($connectFrame);
$client->text($subscribeFrame);
$response = [];
$i = 0;
while ($i < 3) {
sleep(5);
try {
$message = $client->receive();
if (empty($message) || in_array($message, self::BYTE)) {
$i++;
continue;
}
$parsed = $stompFrame->parser($message);
if ($parsed['command'] == $this::STOMP_COMMAND_ERROR) {
$this->logger($this::INFO, 'STOMP return with ERROR command:', $parsed['body']);
$client->close();
break;
}
if (($parsed['command'] == $this::STOMP_COMMAND_MESSAGE) || ($parsed['body'])) {
return json_decode($parsed['body'], true);
}
} catch (Exception $e) {
$this->logger($this::ERROR, 'STOMP error', (array)$e->getMessage());
}
$i++;
}
return $response;
}
i'm trying to download gz file locally from githubarchive with httpclient in php.
When i execute a wget in terminal, the gz is extracted and each folders are downloaded on my computer.
When i do the same in php code, i encounter a 404 each time.
Bellow, my code :
//Symfony\Component\HttpClient\HttpClient;
$httpClient = HttpClient::create();
$response = $httpClient->request('GET', "https://data.gharchive.org/2015-01-01-{0..23}.json.gz");
if (200 !== $response->getStatusCode()) {
throw new \Exception('status code = ' . $response->getStatusCode());
}
when i call wget https://data.gharchive.org/2015-01-01-{0..23}.json.gz in console, every files in gz are downloaded on my computer.
Maybe can i use curl but i have already used it with no success.
{0..23} is a feature of bash called brace expansion. You'll need to recreate this functionality in PHP with something like
for ($i = 0; $i < 24; $i++) {
$response = $httpClient->request('GET', "https://data.gharchive.org/2015-01-01-{$i}.json.gz");
...
}
Drupal 7-soap
This is the error which iam getting in error log and when iam trying to print the
test.wsdl file
SoapFault: looks like we got no XML document in SoapClient->__call()
I have no clue what is the error
My project environment
PHP : 5.4.11
MySQL : 5.5.27 Apache : 2.2.3
OS : CentOS 5.8
code information
function ai_server() {
ini_set('soap.wsdl_cache_ttl', 0);
$server = new SoapServer(file_create_url(variable_get('app_integration_wsdl')), array("trace" => 1, "exceptions" => 0));
$server->addFunction('getData');
$server->addFunction('getId');
$server->addFunction('getInfo');
$server->addFunction('getrightsInfo');
$server->addFunction('updateInfo');
$server->addFunction('resetAppHistory');
//$server->addFunction('resetAppId');
$server->handle();
}
soap client
function ai_sync_test() {
ini_set('soap.wsdl_cache_ttl', 0);
//
// ---------------------------------------------------------------- basic tests
//
// is settings file accessible
$settings_file = variable_get('app_integration_settings');
require_once($settings_file);
$settings_output = is_readable($settings_file) ? 'Ok! Settings file is readable.' : 'Error! Not readable or accessible.';
// is wsdl file accessible
$wsdl_file = variable_get('app_integration_wsdl');
$wsdl_output = is_readable($wsdl_file) ? 'Ok! WSDL file is readable. ' . l('Open it. ', $wsdl_file, array('attributes' => array('target' => '_blank'))) : 'Error! Not readable or accessible. ';
$wsdl_output .= 'You need to define domain name in it into this sections (at the bottom of app_integration.wsdl file): ';
$wsdl_output .= htmlentities('<soap:address location="http://YOUR_DOMAIN_HERE/app_integration/server"/>');
// methods, which integration service is provide
$client = new SoapClient($wsdl_file, array("trace" => 1, "exceptions" => 0));
$methods = $client->__getFunctions();
$methods_output = '';
foreach ($methods as $method) {
$methods_output .= '<li>' . $method . '</li>';
}
2 possible reasons -
You are echoing something in the code, or whitespace characters are getting printed or trailing new line character.
The server SOAP file in php has encode utf8 with BOM, causing apache send back the BOM mark (3 bytes) before the xml response. Encode your php file soap server with utf8 WITH OUT BOM mark.
function strip_bom($str){
return preg_replace( '/^(\x00\x00\xFE\xFF|\xFF\xFE\x00\x00|\xFE\xFF|\xFF\xFE|\xEF\xBB\xBF)/', "", $str );
}
I got some .proto files from A service provider to get stock data.They give me a php code, but I need to use python.I try to do the same thing in python but I failed and failed.The official Docs is not very clear..and my programming skill is so low..
And this is my python code(core part),when I run this code,there will be a error message:"<_Rendezvous> of RPC that terminated with (StatusCode.UNIMPLEMENTED,Method not found:xxxxxxxxxxxxxxxxx.HistoricalQuoteService/getTodayM1Quotes)".I think I didn't connect to the server.When I add the code below:
options.append(update_metadata2)
The error message will changed to:"too many values to unpack"
symbol = common_pb2.Symbol()
symbol.code = "BABA"
symbol.market = common_pb2.US
symbol.type = common_pb2.Stock
market_request = marketData_pb2.MarketDataRequest()
market_request.symbol.code = symbol.code
market_request.symbol.market = symbol.market
market_request.symbol.type = symbol.type
market_request.language = common_pb2.zhHans
print(market_request)
try:
path = os.path.abspath('.')
pemPath = path + '/open_test_cert.pem'
transport_creds = grpc.ssl_channel_credentials(open(pemPath).read())
options = []
update_metadata = {}
update_metadata2 = {}
update_metadata['UserName'] = 'xxxx'
update_metadata['Password'] = 'yyyy'
update_metadata2['grpc.ssl_target_name_override'] = 'open.test.yintongzhibo.com'
options.append(update_metadata)
# options.append(update_metadata2)
channel = grpc.secure_channel("open.test.yintongzhibo.com:9002",transport_creds,options)
# credentials , project= google_auth.default(scopes=(scope1,scope2,scope3))
# credentials , project= google_auth.default()
# http_request = google_auth_transport_requests.Request()
# metadata_plugin = AuthMetadataPlugin(credentials,http_request)
# google_auth_credentials = grpc.metadata_call_credentials(metadata_plugin)
# ssl_credentials = grpc.ssl_channel_credentials(open(pemPath).read())
# composite_credentials = grpc.composite_channel_credentials(ssl_credentials,google_auth_credentials)
# channel = grpc.secure_channel("open.test.yintongzhibo.com:9002",composite_credentials)
# channel = google_auth_transport_grpc.secure_authorized_channel(credentials,request,'open.test.yintongzhibo.com:9002')
stub = historicalQuote_pb2_grpc.HistoricalQuoteServiceStub(channel)
response = stub.getTodayM1Quotes(symbol)
# stub = marketData_pb2_grpc.MarketDataServiceStub(channel)
# response = stub.getMarketData(market_request)
print(response.message)
except Exception as e:
print (e)
So,How should I write python code to achieve the same function of the PHP code?And how can I get more error log?Thanks everyone!
the PHP code is here:
PHP code
I have written a simple chat program using twisted library in Python. Basically I have a server program(server.py) and a chat program ( client.py)
client.py is a simple python script which would connect to the server on a particular port and print the messages on the terminal.
I can run the server.py and the client.py on a local system and I can chat on different terminals.
I would like to integrate the client.py in PHP and be able to chat through the browser.
I am calling python script through exec in PHP. However it is not working.
exec("python client.py")
Any idea, if I am missing anything ?
Not sure if I can help you, but here's some things I'd consider:
Have you tried executing a different command, does that work?
Have you set the permissions of the .php file and Python.exe correctly?
Can you run your command from a terminal window (either Windows/Mac/Linux) from the folder your PHP file is in?
If you've already tried all of these things, I can't think of another solution.. Good luck!
You might find the following program helpful as a starting point. It is designed to run a Python program:
<?php
// Check that test is not FALSE; otherwise, show user an error.
function assert_($test)
{
if ($test === FALSE)
{
echo '<html><head><title>Proxy</title></head><body><h1>Fatal Error</h1></body></html>';
exit(1);
}
}
// Patch this version of PHP with curl_setopt_array as needed.
if (!function_exists('curl_setopt_array')) {
function curl_setopt_array($ch, $curl_options)
{
foreach ($curl_options as $option => $value) {
if (!curl_setopt($ch, $option, $value)) {
return FALSE;
}
}
return TRUE;
}
}
// Fetch the URL by logging into proxy with credentials.
function fetch($url, $proxy, $port, $user, $pwd)
{
$ch = curl_init($url);
assert_($ch);
$options = array(
CURLOPT_PROXY => $proxy . ':' . $port,
CURLOPT_PROXYAUTH => CURLAUTH_NTLM,
CURLOPT_PROXYUSERPWD => $user . ':' . $pwd,
CURLOPT_RETURNTRANSFER => TRUE
);
assert_(curl_setopt_array($ch, $options));
$transfer = curl_exec($ch);
curl_close($ch);
assert_($transfer);
return $transfer;
}
// Run path with stdin and return program's status code.
function order($path, $stdin, &$stdout, &$stderr)
{
$cmd = './' . basename($path);
$descriptorspec = array(
array('pipe', 'r'),
array('pipe', 'w'),
array('pipe', 'w')
);
$cwd = dirname($path);
$process = proc_open($cmd, $descriptorspec, $pipes, $cwd, $_REQUEST);
assert_($process);
for ($total = 0; $total < strlen($stdin); $total += $written)
{
$written = fwrite($pipes[0], substr($stdin, $total));
assert_($written);
}
assert_(fclose($pipes[0]));
$stdout = stream_get_contents($pipes[1]);
assert_($stdout);
assert_(fclose($pipes[1]));
$stderr = stream_get_contents($pipes[2]);
assert_($stderr);
assert_(fclose($pipes[2]));
return proc_close($process);
}
// Collect information to run over the proxy.
# $user = $_REQUEST['user'];
# $pwd = $_REQUEST['pwd'];
// Fetch the URL and process it with the backend.
$transfer = fetch('http://rssblog.whatisrss.com/feed/', 'labproxy.pcci.edu', 8080, $user, $pwd);
$status = order('/home/Chappell_Stephen/public_html/backend.py', $transfer, $stdout, $stderr);
// Check for errors and display the final output.
assert_(strlen($stderr) == 0);
echo $stdout;
?>