I am trying to implement a logging library which would fetch the current debug level from the environment the application runs in:
23 $level = $_SERVER['DEBUG_LEVEL'];
24 $handler = new StreamHandler('/var/log/php/php.log', Logger::${$level});
When I do this, the code fails with the error:
A valid variable name starts with a letter or underscore,followed by any number of letters, numbers, or underscores at line 24.
How would I use a specific Logger:: level in this way?
UPDATE:
I have tried having $level = "INFO" and changing ${$level} to $$level. None of these changes helped.
However, replacing the line 24 with $handler = new StreamHandler('/var/log/php/php.log', Logger::INFO); and the code compiles and runs as expected.
The variable itself is declared here
PHP Version => 5.6.99-hhvm
So the answer was to use a function for a constant lookup:
$handler = new StreamHandler('/var/log/php/php.log', constant("Monolog\Logger::" . $level));
<?php
class Logger {
const MY = 1;
}
$lookingfor = 'MY';
// approach 1
$value1 = (new ReflectionClass('Logger'))->getConstants()[$lookingfor];
// approach 2
$value2 = constant("Logger::" . $lookingfor);
echo "$value1|$value2";
?>
Result: "1|1"
Related
I know this is common error and I have read all answer but my case looks different, at least as a PHP newbie so kindly don't decide action based on question subject.
I have a PHP code which working but I am trying to arrange it in appropriate functions, as in below code but I get following error Warning: Creating default object from empty value in /home/abc/vhosts/localhost/public/portfolio.php on line 16:
<?php
// configuration
require("../includes/config.php");
// prepare portfolio object
$portfolioObject = (object) ["portfolioSummaryArr" => [], "cashInHand" => ""];
function getCashInHand(){
// query database to get cash in hand
$rows = CS50::query("SELECT cash FROM users WHERE username = ?", $_SESSION["username"]);
// get first (and only) row
$row = $rows[0];
$portfolioObject->cashInHand = $row["cash"];
$portfolioObject->portfolioSummaryArr = [11, 22, 33, 44, 55];
}
getCashInHand();
?>
Now after reading all the answers and documentation I think I need some sort of object first so I did this and then I get this error Parse error: syntax error, unexpected '$myObject' (T_VARIABLE) in /home/abc/vhosts/localhost/public/portfolio.php on line 12. I trusted this because something similar is allowed in JS and it works, but guess in PHP isn't so my guess is that using objects created like this you cannot define or access function.
$myObject = new stdClass();
$myObject->demoFunction = function(){
echo "I am coming from demo function.";
}
$myObject->demoFunction();
To me things get more interesting because if I do as in below in my code just after require("../includes/config.php"); then it works and no error, but function definition and access as shown in my first code snippet doesn't work.
// Defining function
function whatIsToday(){
echo "Today is XXX";
}
// Calling function
whatIsToday();
It was just matter of time, I would say. I had to do some reading to understand leverage the object orientation of PHP. Below is how I could resolve all my PHP errors and warnings. Needless to say my favorite debugging methodology "print to screen/terminal", in case of PHP using echo helped a lot.
<?php
// configuration
require("../includes/config.php");
class portfolio{
public $portfolioObject;
public function __construct(){
echo "__construct()</br>";
$this->portfolioObject = new stdClass();
}
public function initialize(){
echo "initialize()";
$portfolioObject = (object) ["portfolioSummaryArr" => [], "cashInHand" => ""];
}
public function getCashInHand(){
// query database to get cash in hand
$rows = CS50::query("SELECT cash FROM users WHERE username = ?", $_SESSION["username"]);
// get first (and only) row
$row = $rows[0];
$this->portfolioObject->cashInHand = $row["cash"];
$this->portfolioObject->portfolioSummaryArr = [11, 22, 33, 44, 55];
}
public function setSessionObject(){
$_SESSION["portfolioSummaryResults"] = $this->portfolioObject;
}
}
$myPortfolio = new portfolio();
$myPortfolio->initialize();
$myPortfolio->getCashInHand();
$myPortfolio->setSessionObject();
render("portfolio/portfolio_results.php", ["title" => "Portfolio"]);
?>
I'm calling a python script from my PHP code, I need to pass 7 variable: a few strings, a couple of array and a matrix.
I tried to use both Shell_Exec and exec(), but I get always the same problem:
matrixdata = sys.argv[7]
IndexError: list index out of range
The first thought was " I passed the wrong number of variable ", but checking they are 7.
This is my python code:
listlabel = str(sys.argv[2])
listdata = (sys.argv[1])
typechart = str(sys.argv[3])
name = str(sys.argv[4])
typedata = str(sys.argv[5])
title = str(sys.argv[6])
matrixdata = sys.argv[7] //this is the matrix
This is my PHP Lines to call it
//json encoding for the array:
$total = json_encode(compact($listlabel));
$event = json_encode(compact($listdata));
$event = json_encode(compact($matrixdata));
exec("python ../home/path../create_chart.py $total $event $chart $name $typedata $title $matrixdata", $output);
//all the parameters exist and the path is correct
I'm passing 7 arguments, I'm getting 7 arguments. I don't understand where the problem is.
Before to added the last matrix, this line was working with 7 elements, instead of 7, I also tried with 8 elements and 9 instead of 7, but no luck.
Let me know if someone can help me, thank you.
I have a bit of PHP code that works fine on my production server but not on my test server. Here is the code:
function callProcedure0(&$connection, $procname, $dofunction)
{
mysqli_multi_query($connection, "CALL " . $procname . "();");
$first_result = 1;
do
{
$query_result = mysqli_store_result($connection);
if ($first_result)
{
$dofunction($query_result);
$first_result = 0;
}
if ($query_result)
{
mysqli_free_result($query_result);
}
$query_result = NULL;
} while(mysqli_next_result($connection));
}
...
function doGenres($in_result)
{
global $genre_array, $game_array, $genre_order_array;
$genre_count = 1;
// foreach is necessary when retrieving values since gaps may appear in the primary key
while ($genre_row = mysqli_fetch_row($in_result)) // line 81 is here!
{
$genre_array[] = $genre_row[0];
$genre_order_array[$genre_row[1] - 1] = $genre_count;
$game_array[] = [[],[]];
$genre_count += 1;
}
}
...
callProcedure0($con, "get_genres_front", doGenres); // line 138 is here!
The "get_genres_front" bit refers to a stored procedure on my database. Here are the errors:
Notice: Use of undefined constant doGenres - assumed 'doGenres' in /opt/lampp/htdocs/keyboard/keyboard.php on line 138
Again, there are no problems on the production server which is using Apache 2.2.23, MySQL 5.1.73-cll, PHP 5.4.26. The test server where things are broken is running Apache 2.4.10, MySQL 5.6.21, PHP 5.5.19.
Did something change in recent software versions? Thanks.
[edit]
This is not a duplicate question. I'm worried about the first error. I already know what to do about the second error which I have deleted.
The code you have posted is wrong, you must pass function name as string and then use call_user_func to invoke this function.
In your callProcedure0 function change
$dofunction($query_result);
to
call_user_func($dofunction, $query_result);
And then call it with the function name as string like this
callProcedure0($con, "get_genres_front", "doGenres");
The above code could work also with invoking the function with
$dofunction($query_result);
on some php versions, but the line where you pass the function name it should be string, otherwise PHP assumes it is a constant.
For some reason, when I try running my php script,
Fatal error: Class 'GeoTools\LatLngCollection' not found in ...
However, I have the classes in the same directory. Namely, I am using https://github.com/jkoreska/RouteboxerPHP
and I have all the scripts in the same directory.
Can someone tell me what I'm doing wrong?
Current script:
$points = [
[48.167, 17.104],
[48.399, 17.586],
[48.908, 18.049],
[49.22253, 18.734436],
[48.728115, 21.255798],
];
$collection = new GeoTools\LatLngCollection($points);
$boxer = new GeoTools\RouteBoxer();
//calculate boxes with 10km distance from the line between points
$boxes = $boxer->box(points, $distance = 10);
//boxes now contain an array of LatLngBounds
//literally have to return string that is printed to STDOUT
print $boxes
?>
When you write GeoTools\LatLngCollection then GeoTools is not the directory, but the namespace of the class LatLngCollection. However, the linked sourcecode defines no namespace at all, and by the way, no class named LatLngCollection. So what you most likely need to do is
require_once(__DIR__ . '/RouteBoxer.class.php');
$points = ...;
$collection = array();
array_push($collection, new LatLng(48.167, 17.104);
array_push($collection, new LatLng(48.399, 17.586);
/...
$boxer = new RouteBoxer();
//...
require includes a file. So I assume that you saved the classes in file "RouteBoxer.class.php" like it is in GitHub.
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;