I am subscribing to data from a MQTT broker with phpMQTT. I have successfully set up a pub / sub routine based on their basic implementation. I can echo the information just fine inside the procmsg() function.
However, I need to take the data I receive and use it for running a few database operations and such. I can't seem to get access to the topic or msg received outside of the procmsg() function. Using return as below seems to yield nothing.
<?php
function procmsg($topic, $msg){
$value = $msg * 10;
return $value;
}
echo procmsg($topic, $msg);
echo $value;
?>
Obviously I am doing something wrong - but how do I get at the values so I can use them outside the procmsg()? Thanks a lot.
I dont know about that lib, but in that code
https://github.com/bluerhinos/phpMQTT/blob/master/phpMQTT.php ,
its possible see how works.
in :
$topics['edafdff398fb22847a2f98a15ca3186e/#'] = array("qos"=>0, "function"=>"procmsg");
you are telling it that topic "edafdff398fb22847a2f98a15ca3186e/#" will have Quality of Service (qos) = 0, and an "event" called 'procmsg'.
That's why you later wrote this
function procmsg($topic,$msg){ ... }
so in the while($mqtt->proc()) this function will check everytime if has a new message (line 332 calls a message function and then that make a call to procmsg of Source Code)
thats are the reason why you cannot call in your code to procmsg
in other words maybe inside the procmsg you can call the functions to process message ej :
function procmsg($topic,$msg){
$value = $msg * 10;
doStuffWithDataAndDatabase($value);
}
Note that you can change the name of the function simply ej :
$topics['edafdff398fb22847a2f98a15ca3186e/#'] = array("qos"=>0, "function"=>"onMessage");
and then :
function onMessage($topic,$msg){
$value = $msg * 10;
doStuffWithDataAndDatabase($value);
}
Sorry for my english, hope this help !
Related
Okay, so We have an issue with a slim php application we use in our api for organizations. When we post an update query to the slim application the data passes through.
The problem is that even though the data passes through to the api and the operation is performed on all the fields. It returns as an error. This is because the when we run the function it's corresponding sql query at the end of the SQL query right smack dab in the where statement right next to the variable from the function call in this format WHERE id=$idnull. With $id being the actual value. The function is structured the same way as our succesfully functiong venue methods. Does anyone have any ideas?
At my wits end trying to resolve this so functions writing to our database for organizations function properly.
function updateOrg($id) {
error_log('addOrg\n', 3, 'php.log');
$request = Slim::getInstance()->request();
$body = $request->getBody();
//var_dump($body);
$org = json_decode($body);
// Handle Checkboxes
if(isset($_REQUEST['recAddEnable'])){ $rAdde = 1; } else $rAdde = 0;
if(isset($_REQUEST['recTelEnable'])){ $rTele = 1; } else $rTele = 0;
if(isset($_REQUEST['recUrlEnable'])){ $rUrle = 1; } else $rUrle = 0;
$sql = "UPDATE usg_usg_orgs
SET
oname='$_REQUEST[oname]',
oemail='$_REQUEST[oemail]',
odesc='$_REQUEST[odesc]',
ourl='$_REQUEST[ourl]',
oadd1='$_REQUEST[oadd1]',
oadd2='$_REQUEST[oadd2]',
ozip='$_REQUEST[ozip]',
ocity ='$_REQUEST[ocity]',
ostate ='$_REQUEST[ostate]',
otel ='$_REQUEST[otel]',
ofax ='$_REQUEST[ofax]',
recTel ='$_REQUEST[recTel]',
recTelEnable= $rTele,
recAdd1='$_REQUEST[recAdd1]',
recAdd2='$_REQUEST[recAdd2]',
recAddEnable= $rAdde,
recCity='$_REQUEST[recCity]',
recCounty='$_REQUEST[recCounty]',
recUrl='$_REQUEST[recUrl]',
recUrlEnable=$rUrle,
recState='$_REQUEST[recState]',
recZip='$_REQUEST[recZip]',
recPubNote='$_REQUEST[recPubNote]',
recPrivNote='$_REQUEST[recPrivNote]',
priContact='$_REQUEST[priContact]',
priTitle='$_REQUEST[priTitle]',
priPhone='$_REQUEST[priPhone]',
priCell='$_REQUEST[priCell]',
priEmail='$_REQUEST[priEmail]',
secContact='$_REQUEST[secContact]',
secTitle='$_REQUEST[secTitle]',
secPhone='$_REQUEST[secPhone]',
secCell='$_REQUEST[secCell]',
secEmail='$_REQUEST[secEmail]',
addContact='$_REQUEST[addContact]',
addTitle='$_REQUEST[addTitle]',
addPhone='$_REQUEST[addPhone]',
addCell='$_REQUEST[addCell]',
addEmail='$_REQUEST[addEmail]',
invContact='$_REQUEST[invContact]',
invTitle='$_REQUEST[invTitle]',
invPhone='$_REQUEST[invPhone]',
invCell='$_REQUEST[invCell]',
invEmail='$_REQUEST[invEmail]',
recModified = UNIX_TIMESTAMP()
WHERE oid= $id";
echo $sql;
try {
$db = getConnection();
$stmt = $db->prepare($sql);
$stmt->execute();
$db = null;
echo json_encode($org);
} catch(PDOException $e) {
echo '{"error":{"text":'. $e->getMessage() .'}}';
}
}
This is the function we use to write to orgs.
Below is the function we use to write to the api to write orgs.
jQuery.ajax({
type: "post",
url: "//usasportgroup.com/api3/orgs/update/"+oid,
data: {
oname:jQuery('#onameMF').val(),
oadd1:jQuery('#oadd1MF').val(),
oadd2:jQuery('#oadd2MF').val(),
otel:jQuery('#otelMF').val(),
ocity:jQuery('#ocityMF').val(),
ostate:jQuery('#ostateMF').val(),
ozip:jQuery('#ozipMF').val(),
ourl:jQuery('#ourlMF').val(),
oemail:jQuery('#oemailMF').val(),
recAdd1:jQuery('#recAdd1MF').val(),
recAdd2:jQuery('#recAdd2MF').val(),
recAddEnable:jQuery('#recAddEnableMF').val(),
recTel:jQuery('#recTelMF').val(),
recTelEnable:jQuery('#recTelEnableMF').val(),
recZip:jQuery('#recZipMF').val(),
recCity:jQuery('#recCityMF').val(),
recState:jQuery('#recStateMF').val(),
recUrl:jQuery('#recUrlMF').val(),
recUrlEnable:jQuery('#recUrlEnableMF').val(),
recPubNote:jQuery('#recPubNoteMF').val(),
priContact:jQuery('#priContactMF').val(),
priTitle:jQuery('#priTitleMF').val(),
priPhone:jQuery('#priPhoneMF').val(),
priEmail:jQuery('#priEmailMF').val(),
priCell:jQuery('#priCellMF').val(),
secContact:jQuery('#secContactMF').val(),
secTitle:jQuery('#secTitleMF').val(),
secPhone:jQuery('#secPhoneMF').val(),
secEmail:jQuery('#secEmailMF').val(),
secCell:jQuery('#secCellMF').val(),
invContact:jQuery('#invContactMF').val(),
invTitle:jQuery('#invTitleMF').val(),
invPhone:jQuery('#invPhoneMF').val(),
invEmail:jQuery('#invEmailMF').val(),
invCell:jQuery('#invCellMF').val(),
addContact:jQuery('#addContactMF').val(),
addTitle:jQuery('#addTitleMF').val(),
addPhone:jQuery('#addPhoneMF').val(),
addEmail:jQuery('#addEmailMF').val(),
addCell:jQuery('#addCellMF').val()},
dataType: "json",
success: function(data) {
jQuery('#orgModal').modal('hide');
},
error: function(data) {
console.log(data);
}
});
This is where how we get the ID:
$app->post('/update/:id', 'updateOrg');
As stated in the comment chain below
This is an example of what we return from our error function WHERE oid= 1216null
Anyone have any ideas? Anyone? This has been plaguing us since we first built the system.
I think it might be server side because the ID goes through and is used but at the end of the statement there's a null that is not attached to the number. I've checked.
Before you ask bound parameters are a long term goal.
Upon further inspection it seems that it returns a statusText of Okay. with a status of 200.
Okay, the issue upon lots of testing and research was a lot simpler than I had thought. It turns out for some reason in this api piece we were still actively echoing the SQL in addition to the answer. Causing it to return with an http response of 200. That was the issue the whole stinking time. I commented out the echo $sql Command and it now works exactly like it was supposed to across the board. I am terribly sorry for wasting every body's time with what was an extremely obvious solution in retrospect.
Well I have a function getDaysTotal in my model say estimate.php.
If in my view.php if I use
echo $model->DaysTotal;
I get the value 3. But if I do it again
echo $model->DaysTotal;
Now I get 1. Any idea, why I am getting it like this.
This is happening for any function in estimate.php.
If I am using it for second time the result is weird.
Am I doing anything wrong here? How can I correct this?
Thanks.
Here is the code for getTotalDays function:
public function getDaysTotal() {
$this->discharge_date = strtotime($this->discharge_date);
$this->admission_date = strtotime($this->admission_date);
$datediff = ($this->discharge_date - $this->admission_date);
$fraction_days = ($datediff/(60*60*24));
if ($fraction_days < 1){
return 1;
}elseif(($datediff)%(60*60*24) < 10800){
$option2 = floor($datediff/(60*60*24));
return $option2;
}elseif(($datediff%86400) > 10800 && ($datediff%86400)<21600) {
$option3 = ceil($datediff/(60*60*24)*2)/2;
return $option3;
}elseif (($datediff%86400) >21600){
$option4= ceil($datediff/86400);
return $option4;
}
Your getter changes your object:
public function getDaysTotal() {
$this->discharge_date = strtotime($this->discharge_date);
$this->admission_date = strtotime($this->admission_date);
You should not to do it. On next call strtotime(int) returns false for both lines.
Try followed:
public function getDaysTotal() {
$discharge_date = strtotime($this->discharge_date);
$admission_date = strtotime($this->admission_date);
$datediff = ($discharge_date - $admission_date);
Used aux vars here, without any object state modifying.
It's funny that you're getting anything because "echo $var" might be a non-object.
<?php
$a = 6;
echo $a -> b;
?>
PHP Notice: Trying to get property of non-object.
IN PHP the right pointing arrow "->" is used to access the component parts of an object, in php it is similar to "::" or the humble "." in languages like java and the C family.
Without more context it is impossible to tell what exactly is happening in you're case but perhaps this page on the "->" will be helpful for you.
If that dosn't give you what you need here is a general PHP note card
I am working on multilingual application with a centralized language system. It's based on language files for each language and a simple helper function:
en.php
$lang['access_denied'] = "Access denied.";
$lang['action-required'] = "You need to choose an action.";
...
return $lang;
language_helper.php
...
function __($line) {
return $lang[$line];
}
Up til now, all strings were system messages addressed to the current user, hence I always could do it that way. Now, I need create other messages, where the string should depend on a dynamic value. E.g. in a template file I want to echo the number of action points. If the user only has 1 point, it should echo "You have 1 point."; but for zero or more than 1 point it should be "You have 12 points."
For substitution purposes (both strings and numbers) I created a new function
function __s($line, $subs = array()) {
$text = $lang[$line];
while (count($subs) > 0) {
$text = preg_replace('/%s/', array_shift($subs), $text, 1);
}
return $text;
}
Call to function looks like __s('current_points', array($points)).
$lang['current_points'] in this case would be "You have %s point(s).", which works well.
Taking it a step further, I want to get rid of the "(s)" part. So I created yet another function
function __c($line, $subs = array()) {
$text = $lang[$line];
$text = (isset($sub[0] && $sub[0] == 1) ? $text[0] : $text[1];
while (count($subs) > 0) {
$text = preg_replace('/%d/', array_shift($subs), $text, 1);
}
return $text;
}
Call to function looks still like __s('current_points', array($points)).
$lang['current_points'] is now array("You have %d point.","You have %d points.").
How would I now combine these two functions. E.g. if I want to print the username along with the points (like in a ranking). The function call would be something like __x('current_points', array($username,$points)) with $lang['current_points'] being array("$s has %d point.","%s has %d points.").
I tried to employ preg_replace_callback() but I am having trouble passing the substitute values to that callback function.
$text = preg_replace_callback('/%([sd])/',
create_function(
'$type',
'switch($type) {
case "s": return array_shift($subs); break;
case "d": return array_shift($subs); break;
}'),
$text);
Apparently, $subs is not defined as I am getting "out of memory" errors as if the function is not leaving the while loop.
Could anyone point me in the right direction? There's probably a complete different (and better) way to approach this problem. Also, I still want to expand it like this:
$lang['invite_party'] = "%u invited you to $g party."; should become Adam invited you to his party." for males and "Betty invited you to her party." for females. The passed $subs value for both $u and $g would be an user object.
As mentionned by comments, I guess gettext() is an alternative
However if you need an alternative approach, here is a workaround
class ll
{
private $lang = array(),
$langFuncs = array(),
$langFlags = array();
function __construct()
{
$this->lang['access'] = 'Access denied';
$this->lang['points'] = 'You have %s point{{s|}}';
$this->lang['party'] = 'A %s invited you to {{his|her}} parteh !';
$this->lang['toto'] = 'This glass seems %s, {{no one drank in already|someone came here !}}';
$this->langFuncs['count'] = function($in) { return ($in>1)?true:false; };
$this->langFuncs['gender'] = function($in) { return (strtolower($in)=='male')?true:false; };
$this->langFuncs['emptfull'] = function($in) { return ($in=='empty')?true:false; };
$this->langFlags['points'] = 'count';
$this->langFlags['toto'] = 'emptfull';
$this->langFlags['party'] = 'gender';
}
public function __($type,$param=null)
{
if (isset($this->langFlags[$type])) {
$f = $this->lang[$type];
preg_match("/{{(.*?)}}/",$f,$m);
list ($ifTrue,$ifFalse) = explode("|",$m[1]);
if($this->langFuncs[$this->langFlags[$type]]($param)) {
return $this->__s(preg_replace("/{{(.*?)}}/",$ifTrue,$this->lang[$type]),$param);
} else {
return $this->__s(preg_replace("/{{(.*?)}}/",$ifFalse,$this->lang[$type]),$param);
}
} else {
return $this->__s($this->lang[$type],$param);
}
}
private function __s($s,$i=null)
{
return str_replace("%s",$i,$s);
}
}
$ll = new ll();
echo "Call : access - NULL\n";
echo $ll->__('access'),"\n\n";
echo "Call : points - 1\n";
echo $ll->__('points',1),"\n\n";
echo "Call : points - 175\n";
echo $ll->__('points',175),"\n\n";
echo "Call : party - Male\n";
echo $ll->__('party','Male'),"\n\n";
echo "Call : party - Female\n";
echo $ll->__('party','Female'),"\n\n";
echo "Call : toto - empty\n";
echo $ll->__('toto','empty'),"\n\n";
echo "Call : toto - full\n";
echo $ll->__('toto','full');
This outputs
Call : access - NULL
Access denied
Call : points - 1
You have 1 point
Call : points - 175
You have 175 points
Call : party - Male
A Male invited you to his parteh !
Call : party - Female
A Female invited you to her parteh !
Call : toto - empty
This glass seems empty, no one drank in already
Call : toto - full
This glass seems full, someone came here !
This may give you an idea on how you could centralize your language possibilities, creating your own functions to resolve one or another text.
Hope this helps you.
If done stuff like this a while ago, but avoided all the pitfalls you are in by separating concerns.
On the lower level, I had a formatter injected in my template that took care of everything language-specific. Formatting numbers for example, or dates. It had a function "plural" with three parameters: $value, $singular, $plural, and based on the value returned one of the latter two. It did not echo the value itself, because that was left for the number formatting.
The whole translation was done inside the template engine. It was Dwoo, which can do template inheritance, so I set up a master template with all HTML structure inside, and plenty of placeholders. Each language was inheriting this HTML master and replaced all placeholders with the right language output. But because we are still in template engine land, it was possible to "translate" the usage of the formatter functions. Dwoo would compile the template inheritance on the first call, including all subsequent calls to the formatter, including all translated parameters.
The gender problem would be getting basically the same soluting: gender($sex, $male, $female), with $sex being the gender of the subject, and the other params being male or female wording.
Perhaps a better aproach is the one used by function t in Drupal, take a look:
http://api.drupal.org/api/drupal/includes!bootstrap.inc/function/t/7
http://api.drupal.org/api/drupal/includes!bootstrap.inc/function/format_string/7
I hope the title isn't too confusing, I'll try to explain better below.
Suppose I have a function in a separate file, functions.php:
function divide($num1, $num2) {
if ($num1 == 0 || $num2 == 0) {
trigger_error("Cannot divide by 0", E_USER_ERROR);
} else {
return ($num1 / $num2);
}
}
And another file that calls it:
include "functions.php";
echo divide(10, 0);
My error is
Fatal error: Cannot divide by 0 in
C:\Users\Derek\Desktop\projects\functions.php on line 5
My question is, how do I make that error instead point to the location of the error in the main code, so I instead get:
Fatal error: Cannot divide by 0 in
C:\Users\Derek\Desktop\projects\main.php on line 3
The particular reason I want this is because I have a function called load_class that simply finds a PHP file and instantiates the object inside, but if given an incorrect file name, it reports an error from inside load_class, which is technically true, but it's not particularly helpful if I don't remember where I called load_class in the first place. I would like the error to point to the file that called load_class incorrectly.
Also, I would like to write a function error() (something like below) that when given a message as a parameter would throw more "meaningful" error messages, but when done that way, the error always says it comes from error(), not from where the error actually came from!
For example, in an error.php:
/**
* error()
*
* Throws an error of a certain type
*
* #param string $type The type of error. "Fatal", "warning," or "notice"
* #param string $message A description of the error
* #return void
*/
function error($type, $message) {
switch (strtolower($type)) {
case 'fatal':
trigger_error($message, E_USER_ERROR);
break;
case 'notice':
trigger_error($message, E_USER_NOTICE);
default:
trigger_error($message, E_USER_WARNING);
break;
}
}
And in an index.php
error("fatal", "A sample warning!");
My error given is:
Fatal error: A sample warning! in
C:\Users\Derek\Desktop\projects\synthesis\sys\Error.php on line 45
But the error didn't occur in error.php, it happened in index.php! How can I make it show where it really came from?
The debug_backtrace function allows you to obtain the stacktrace as an array. You can pick the original location from there.
Next to that you need to slip into the error message to make this look-alike. Example:
function divide($num1, $num2) {
if ($num1 == 0 || $num2 == 0) {
trigger_error_original("Cannot divide by 0", E_USER_ERROR);
} else {
return ($num1 / $num2);
}
}
function trigger_error_original($message, $type) {
$trace = debug_backtrace(FALSE);
list($location) = array_slice($trace, 1, 1) + array('file' => 'unknown', 'line' => 'unknown');
$message .= sprintf(" in %s on line %d\nTriggered", $location['file'], $location['line']);
trigger_error($message, $type);
}
divide(1, 0);
The error message than shows something like:
> php test-pad.php
Fatal error: Cannot divide by 0 in test-pad.php on line 18
Triggered in test-pad.php on line 15
The downside of this is, that you need to change your code to have this "feature". If you need this for debugging your own code, it's much better that you enable backtraces in your logs. The Xdebug extension does this for you, or you can write your own error handler that takes care of that.
See as well the related question Caller function in PHP 5?. I used array_slice so that you could create an additional parameter to define the number of steps you want to go "up" in the backtrace.
Use debug_backtrace(), and debug_print_backtrace() for a full call stack. These are especially effective when using Xdebug, which will override the function to colorize the output.
I have this same problem...
#1: while 10/0 = ERROR, 0/10 = 0 is perfectly legal, you shouldn't have an exception for that.
#2: when you include a file, it effectively becomes part of this new file, so perhaps you might have to toy a little bit with things like __FILE__ and see if you can make it point it to the file before it gets included in the other file..
You can use xdebug - it will show you the stacktrace or you can register your own error handndler and display the stacktrace. Just check the example in php.net for set_error_handler().
Maybe exceptions are better to use in your case. You get the full stacktrace and can locate where the function was called without relying on some tricky code :)
First let me say sorry for the amount of code I'm posting below I'm going to try and keep it as short as possible but this is built on top of my MVC (lightweight-mvc)
Ok So my Problem is that for some reason php is throwing a fatal error on code that should not be being used in my current code,
So how this works I have my MVC witch used the first 2 parts of the url to know what its loading, the problem is I'm building a Moulder CMS into my MVC so it's boot strapping twice,
So here is my Problem,
http://{domain}/admin/control/addon/uploader/method/uploadCheck/
I'm using the above now let me explain a little into that the /admin/control are for the main MVC System it auto-loads the Admin controller then fires the controlAction method from the controller much the same as most MVC's,
The next part are URL paramters that build an array the same as GET or POST would
array('addon'=>'uploader', 'method'=>'uploadCheck')
So from that my control action will auto load as is the code below
public function controlAction(){
global $_URL;
if(cleanData::URL("addon")){
$addonName = "addon_".cleanData::URL("addon");
$methodName = (cleanData::URL("method"))? cleanData::URL("method")."Action" : "indexAction";
echo $methodName;
$addon = new $addonName();
$addon->$methodName();
return;
}else{
$this->loadView("CMS/controll");
}
}
cleanData::URL is an abstract method that just returns the value of the key provided though addSlashes()
So as you can see from the code below it will then use the autoloader to load the module(AKA addon)
Just so you can follow the auto loader works in a simpler version of the Zend Frame work autoloader _ so you have class name addon_admin that would be inside file admin.php that is in the folder addon so the autoloader will load addon/admin.php
So As above with my URL and controlAction it's loading addon/uploader.php and as such this is the contents
<?php
class addon_uploader extends Addons{
public function uploadCheckAction(){
echo 0;
}
public function uploaderAction(){
if (!empty($_FILES)) {
$tmpFile = $_FILES['Filedata']["tmp_name"];
$newLock = "../uploads/".end(explode('/', $tmpFile).$_FILES['Filedata']['name']);
move_uploaded_file($tmpFileName, $newLock);
$POSTback = array(
'name' => $_FILES['Filedata']['name'],
'type' => $_FILES['Filedata']['type'],
'tmp_name' => $newLock,
'error' => $_FILES['Filedata']['error'],
'size' => $_FILES['Filedata']['size']
);
echo json_enocde($POSTback);
}
}
}
?>
But as you can see from my URL its using the uploadCheckAction method witch for debugging i have set so it always says false (AKA 0),
But i seem to get this error:
Fatal error: Only variables can be passed by reference in C:\xampp\htdocs\FallenFate\addon\uploader.php on line 11
But line 11 is $newLock = "../uploads/".end(explode('/', $tmpFile).$_FILES['Filedata']['name']); witch should not be being used could any one provide any help into why this would occur and how i could fix it
end() PHP Manual needs an expression of a single variable (more precisely an array), but not a function return value or any other type of expression.
I think that's basically the cause of your error, more specifically with your code:
$newLock = "../uploads/".end(explode('/', $tmpFile).$_FILES['Filedata']['name']);
you're even driving this far beyond any level of treatment PHP can cope with:
you concatenate an array with a string (which results in a string).
you run end() on that string - not on a variable, not even an array.
I have no clue what you try to do with the code, but I can try:
$filename = $_FILES['Filedata']['name'];
$parts = explode('/', $tmpFile);
$last = end($parts);
$newLock = "../uploads/". $last . $filename;
Or probably even only this:
$filename = $_FILES['Filedata']['name'];
$newLock = "../uploads/". $filename;