I have a PHP-script which takes a POST-variable from a request, does something with it (in this case it's an memcached request for the specific key) and sends it back via JSON.
The complicated part is that I don't host this script on the same Server as I do with the script doing the request. So I tried to use CORS. My browser tells me that I haven't set the Access-Control-Allow-Origin-Header, but I did as you can see. So I guess that I set it wrong. But I haven't really dealt with headers in PHP so I have really no clue what do do. I already searched (also on Stackoverflow) but all I found is that I have to set this header, what I did...
Of ourse the memcache-part isn't really interesting for solving the problem but I thought it would be better to let you guys take a look at the complete code, so here you go:
<?php
header("Access-Control-Allow-Origin: * ");
$key = $_POST["key"];
$json = "";
if($key != "")
{
define('MEMCACHED_HOST', '127.0.0.1');
define('MEMCACHED_PORT', '11211');
$memcache = new Memcache;
$memcache->connect(MEMCACHED_HOST, MEMCACHED_PORT);
$value = memcache->get($key);
$json_array = array("status" => "done" , "key" => $key, "value" => $value);
$json = json_encode($json_array);
}
else
{
$json_array = array("status" => "empty");
$json = json_encode($json_array);
}
echo $json;
?>
Inserting some lines into the Apache .conf file did it. If someone is interested, these lines can be found here. I still don't know why it didn't worked with the headers in PHP. Maybe I did something wrong with the client. But it's working now :)
Related
Google Geocode use to work for me but does not anymore. Everything I've tried returns false. It doesn't even give a clue as to why. I've tried changing the API key, I've tried different methods to connect (I prefer using simplexml_load_file). It does work if I type the URL directly into the a browser window but not from my website or even from my localhost. Does anyone have suggestions on what to try next or an alternative to Googles Geocode service?
Here is some code that I've been using that Json / XML results.
//URL SAVE ADDRESS
date_default_timezone_set("America/Chicago");
$address = "1600 Amphitheatre Parkway, Mountain View, CA 94043";
$address = urlencode($address);
// GOOGLE URL
$url = "https://maps.googleapis.com/maps/api/geocode/xml?address=". $address ."&sensor=false&key=AIzaSyDrGe_qr4ofea8WhZFhnPGsXNQtTiQwGhw";
echo $url; //TEMP
$xml = simplexml_load_file($url) OR $ex['tblx'] = "Unable to load XML from Googleapis.";
if(empty($xml)) {
$ex['tblx'] = "Googleapis return no values.";
} elseif("" == $xml) {
$ex['tblx'] = "Geocode problem with address, revise and retry.";
} elseif("OK" != $xml->status) {
$ex['tblx'] = "Geocode: " . ("ZERO_RESULTS" == $xml->status? "Not Found": substr($xml->status,0,30));
} else{
$dvtby0 = $uca['y0'] = (double)$xml->result->geometry->location->lat; //x
$dvtbx0 = $uca['x0'] = (double)$xml->result->geometry->location->lng;
$dvtby1 = $uca['y1'] = (double)$xml->result->geometry->viewport->southwest->lat; //a
$dvtbx2 = $uca['x1'] = (double)$xml->result->geometry->viewport->southwest->lng;
$dvtbx1 = $uca['x2'] = (double)$xml->result->geometry->viewport->northeast->lng; //b
$dvtby2 = $uca['y2'] = (double)$xml->result->geometry->viewport->northeast->lat;
}//endif
if($ex) {
var_dump($ex);
}
die("did it work?");
geocoder.ca for north america
opencage or geocode.xyz for the world
pelias as standalone
there are lots of options in 2018
The problem here turned out to be the version of PHP. It's really weird and hard to troubleshoot. simplexml_load_file($url) was not returning an object. It wasn't even returning false. The only clue that it was something other that code problem. Upgrade to version 5.6 and it works ok.
I am working on some old Flash as2 application that worked fine until something happened.
Most likely it's Flash 13 upgrade but I can't figure out why.
PHP version on server didn't changed.
I have following function in Flash that packs XML with another function and send to printcard.php:
var xmlDoc:Object=toXML();
xmlDoc.send(_global.phpPath + "printcard.php","_blank");
printcard.php should take $_POST XML and do some work with it ...
$data = GET_POST_XML();
$xml = new XML($data);
$arrCardPage = $xml->getBranches("card", "CardPage");
$cardPage = $arrCardPage[0];
And really ancient GET_POST_XML() function that worked fine until recently:
global $HTTP_POST_VARS, $HTTP_RAW_POST_DATA;
if( $HTTP_RAW_POST_DATA == null || !isset($HTTP_RAW_POST_DATA) ){
$xmldoc = '';
reset($HTTP_POST_VARS);
while(list($k, $v) = each($HTTP_POST_VARS)) {
$xmldoc.=$k.'='.$v;
};
$xmldoc = stripslashes($xmldoc);
$xmldoc = str_replace('<?php xml_version', '<?php xml version', $xmldoc);
return $xmldoc;
} else {
return $HTTP_RAW_POST_DATA;
};
Problem is that $data is empty - I have no XML.
On phpinfo I have:
_POST["<card_id"]:
\"0\" shared=\"0\" doubleside=\"1\" BgColorPicker=\"0\" bwColors=\"1\" showBg=\"1\" name=\"\"><CardPage h=\"17.99\" w=\"46.99\"><layerFront><CardLayer bg=\"16777215\" bgImageURL=\"\"><elements><OvalElement bgAlpha=\"100\" lineAlpha=\"100\" bgColor=\"16777215\" lineColor=\"0\" lineSize=\"0.35\" useFill=\"true\" useLine=\"true\" rotation=\"0\" h=\"7.76\" w=\"22.93\" y=\"4.58\" x=\"22.57\" /></elements></CardLayer></layerFront><layerBack><CardLayer bg=\"16777215\" bgImageURL=\"\"><elements /></CardLayer></layerBack></CardPage></card>
What did I missed?
use
$data = file_get_contents('php://input');
instead of
$data = GET_POST_XML();
OK, here's update in case someone stack with same issue:
Send command is deprecated from Flash version 13.
It doesn't send RAW POST DATA anymore.
However, SendAndLoad still works fine.
Couldn't find anything on Google or official Adobe release notes about this.
I'm here again, learning more and more about PHP, but still have some problems for my scenario, most of my scenario has been programmed and solved without problem, but I found an issue, but to understand it, I need to explain it first:
I have a PHP script which can be invoked by any client and its work is to receive a request, ping to a proxy from a list which I define manually, to know if a proxy is available, if it is available, I proceed to retrieve a response using "curl" with a POST method. The logic is like this:
$proxyList = array('192.168.3.41:8013'=> 0, '192.168.3.41:8023'=>0, '192.168.3.41:8033'=>0);
$errorCounter = 0;
foreach ($proxyList as $key => $value){
if(!isUrlAvailable($key){ //It means it is NOT available so I count errors
$errorCounter++;
} else { //It means it is AVAILABLE
$result = callThisProxy($key);
}
}
The function "isUrlAvailable" uses a $fsockopen to know if the proxy is available. If not, I make a POST with CURL as mentioned before, the function has callThisProxy() something like:
$ch = curl_init($proxyUrl);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,'xmlQuery='.$rawXml);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$info = curl_exec ($ch);
if($isDebug){echo 'Info in the moment: '.$info.'<br/>';}
curl_close ($ch);
But, we're testing some scenarios, what happen if I turn off the proxy between the verification of the proxy availability and the call? I mean:
foreach ($proxyList as $key => $value){
if(!isUrlAvailable($key){ //It means it is NOT available so I count errors
$errorCounter++;
} else { //It means it is AVAILABLE
$result = callThisProxy($key);//What happen if I kill the proxy when the result is being processed?
}
}
I tested it and when I do that, the $result comes as empty string ''. But the problem is that I lost that request, and my goal is to retry it with the next $key which is a proxy. So, I've been thinking of a "do, while" when I invoke the result. But not sure, if it is ok or there's a better way to do it, so please I ask for help with this issue. Thanks in advance for your time any answer is welcome. Thanks.
Maybe something like:
$result = "";
while ($result == "")
{
foreach ($proxyList as $key => $value)
{
if (!isUrlAvailable($key))
{
$errorCounter++;
}
else
{
$result = callThisProxy($key);
}
}
}
// Now check $result, which should contain the first successful callThisProxy()
// result, or nothing if none of the keys worked.
You could just keep a list of proxies that you still need to try. When you hit the error or get a valid response then you remove the proxy from the list of proxies to try. If you do not get a good response then keep it in the list and try it again later.
$proxiesToTry = $proxyList;
$i = 0;
while (count($proxiesToTry) != 0) {
// reset to beginning of array
if($i >= count($proxiesToTry))
$i = 0;
$proxy = $proxiesToTry[$i];
if (!isUrlAvailable($proxy)) { //It means it is NOT available so I count errors
$errorCounter++;
unset($proxiesToTry[$i]);
} else { //It means it is AVAILABLE
$result = callThisProxy($proxy);
if($result != "") // If we got a response remove it from the array of proxies to try.
unset($proxiesToTry[$i]);
}
$i++;
}
NOTE: You will never break out of this loop if you don't ever get a valid response from some proxy.
I am working on a custom script to automatically send out invites and reminders. I have everything working fine up until a point. My function to send invites looks like this:
function sendInvites($iSurveyID) {
$oSurvey = Survey::model()->findByPk($iSurveyID);
if (!isset($oSurvey)) {
die("could not load survey");
}
if(!tableExists("{{tokens_$iSurveyID}}")) {
die("survey has no tokens or something");
}
$SQLemailstatuscondition = "emailstatus = 'OK'";
$SQLremindercountcondition = '';
$SQLreminderdelaycondition = '';
$iMaxEmails = (int)Yii::app()->getConfig("maxemails");
$iMaxReminders = 1;
if(!is_null($iMaxReminders)) {
$SQLremindercountcondition = "remindercount < " . $iMaxReminders;
}
$oTokens = Tokens_dynamic::model($iSurveyID);
$aResultTokens = $oTokens->findUninvited(false, $iMaxEmails, true, $SQLemailstatuscondition, $SQLremindercountcondition, $SQLreminderdelaycondition);
if (empty($aResultTokens)) {
die("No tokens to send invites to");
}
$aResult = emailTokens($iSurveyID, $aResultTokens, 'invite');
}
I also have a simple little file that starts up Yii:
Yii::createApplication('LSYii_Application', APPPATH . 'config/config' . EXT);
Yii::app()->loadHelper('admin/token');
Yii::app()->loadHelper('common');
Everything works as expected up until I actually try to send emails to the tokens. I've tracked the problem down to the following, on of the functions called by emailTokens has this in it:
$clang = Yii::app()->lang;
$aBasicTokenFields=array('firstname'=>array(
'description'=>$clang->gT('First name'),
'mandatory'=>'N',
'showregister'=>'Y'
),
The Yii::app()->lang part seems to be causing issues because then php is unable to call the gT method. However, when LimeSurvey is running "properly" this never happens. I can't even seem to find where "lang" is in the LimeSurvey source.
What can I do to make it work?
Why do you make it so hard on yourself and not use the RemoteControl2 API ?
See http://manual.limesurvey.org/wiki/RemoteControl_2_API#invite_participants
On that page you will also find a PHP example script.
maybe
Yii::import('application.libraries.Limesurvey_lang');
$clang = new Limesurvey_lang($oTokens->language);
So in keeping with my last question, I'm working on scraping the friends feed from Twitter. I followed a tutorial to get this script written, pretty much step by step, so I'm not really sure what is wrong with it, and I'm not seeing any error messages. I've never really used cURL before save from the shell, and I'm extremely new to PHP so please bear with me.
<html>
<head>
<title>Twitcap</title>
</head>
<body>
<?php
function twitcap()
{
// Set your username and password
$user = 'osoleve';
$pass = '****';
// Set site in handler for cURL to download
$ch = curl_init("https://twitter.com/statuses/friends_timeline.xml");
// Set cURL's option
curl_setopt($ch,CURLOPT_HEADER,1); // We want to see the header
curl_setopt($ch,CURLOPT_TIMEOUT,30); // Set timeout to 30s
curl_setopt($ch,CURLOPT_USERPWD,$user.':'.$pass); // Set uname/pass
curl_setopt($ch,CURLOPT_RETURNTRANSER,1); // Do not send to screen
// For debugging purposes, comment when finished
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,0);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,0);
// Execute the cURL command
$result = curl_exec($ch);
// Remove the header
// We only want everything after <?
$data = strstr($result, '<?');
// Return the data
$xml = new SimpleXMLElement($data);
return $xml;
}
$xml = twitcap();
echo $xml->status[0]->text;
?>
</body>
</html>
Wouldn't you actually need everything after "?>" ?
$data = strstr($result,'?>');
Also, are you using a free web host? I once had an issue where my hosting provider blocked access to Twitter due to people spamming it.
note that if you use strstr the returend string will actually include the needle-string. so you have to strip of the first 2 chars from the string
i would rather recommend a combination of the function substr and strpos!
anways, i think simplexml should be able to handle this header meaning i think this step is not necessary!
furthermore if i open the url i don't see the like header! and if strstr doesnt find the string it returns false, so you dont have any data in your current script
instead of $data = strstr($result, '<?'); try this:
if(strpos('?>',$data) !== false) {
$data = strstr($result, '?>');
} else {
$data = $result;
}