I am trying to use my logger to dump variables to my logfile.
I need it to write down arrays within arrays.
Could you explain please how to do this ? (I am not sure of how to pass the sub-array of the rest of the array but here's what I came up with, which obviously is missing something)
Thanks
function logRec($param)
{
if(!isset($param))
return;
foreach($param as $key=>$value)
{
if(is_array($value))
{
echo "<b>nested array</b><br />";
logRec(next($param));
}
else
{
echo $param;
return;
}
}
}
$par = array("ABC","DEF",array("Apple","Peach","Melon",array("Cube","Sphere","Pyramid")));
logRec($par);
I would just do this:
write_to_log_or_whatever(print_r($par, true));
The second parameter on print_r() sets it to return the output, rather than sending it to the buffer as usual.
If seeing it on too many lines isn't good for your log file, the other thing you can do is json_encode() it, but then you have to decide if having JSON-encoded data in your log is helpful. If you are going through your logs manually, it can be. But, if you have log file analysis tools, it often is a pain.
Related
I'd like to know from a design POV whether changing the value of a constant per HTTP request is discouraged or perfectly ok.
I have a few constants that are defined at the start of a PHP script and they're used to figure out a particular context (what is the user trying to do at the time). The constants are never changed throughout the lifecycle of the script so they conform with the rules of constants and they work well. However, the values of these constants depends on what the user's doing. I'm wondering whether this is discouraged or perfectly acceptable in PHP.
<?php
// This function is only run once per HTTP request at the start
function new_paper() {
define('NEW_PAPER', 1);
define('NEW_VERSION', 0);
}
// This function is also only run once per HTTP request at the start
function new_paper_version() {
define('NEW_PAPER', 0);
define('NEW_VERSION', 1);
}
// This function is subsequently called by both functions above
function a_handler_of_sorts() {
if (NEW_PAPER) {
// Do something if it's a new paper
}
elseif (NEW_VERSION) {
// Do something if it's a new version
}
else {
}
}
In no circumstances are both new_paper() and new_paper_version() run in the same HTTP request.
A typical use case would be something like:
define('DEBUG', !empty($_GET['debug']));
if (DEBUG) echo 'some debugging statement';
Obviously don't do this only based on a query parameter, especially not in production, but you get the idea.
So, yes, setting constant values based on the request is fine. Whether this is the best thing to do in your particular case is questionable and I don't know. I'd really reserve it for "meta" values like debug flags, not for values which are essentially function parameters, inputs for your business logic. Do this sparingly.
"Constant values" which influence how every script works independently of the request would be something like config files or environment variables, e.g. containing database access credentials and such.
Constants should not change during the request but as you said yours don't so I think you're OK there.
They represent fixed things such as how many DB connections are allowed, the name of the application etc. If you're trying to use them to store the state of your application then you could consider doing something like:
<?php
define('STATE_PAPER', 0);
define('STATE_VERSION', 1);
define('STATE_INVALID', 2);
$applicationState = null;
if (someCheckForPaper() === true) {
$applicationState = NEW_PAPER;
} else if (someCheckForVersion() === true) {
$applicationState = NEW_VERSION;
} else {
$applicationState = STATE_INVALID;
}
// Save $applicationState somewhere... maybe session?
// Somewhere else
if ($applicationState === STATE_PAPER) {
...
}
I read that file_get_content is synchronous, but when I tried the code below I dont' think so :
$url = "http://foo.com";
$a = array("file11.php", "file2.php", "file3.php");
foreach ($a as $file)
{
$final = $url . "/" . $file;
print "Calling $final ...";
$res = file_get_contents($final);
if ($res)
print "OK";
else
print "ERR!";
print "<br>";
}
Each file executes some complex tasks, so I know the minimal excution time of any script, but this code runs very fastly and seems not to wait each request ! How can I wait for each file request?
Thanks :)
The above code is definitely synchronous. So if you say that the code exits after a few seconds, while it should be a lot longer, then you probably have a problem with the code.
Try to wrap this code in a try {} catch. And print the error. See what it says.
Try { code here } catch (Exception $e) { }
Also, most default settings in the php.ini for MAX_EXECUTION for a script is 30 seconds. After that it will exit on a fatal timeout error too. Check the setting in your php.ini and adjust it to your needs.
Edit:
Gathering your comments, I now assume you are trying to execute the php files you are referring to. This makes your question very confusing and the tags just wrong.
The code you use in your example only reads the contents of the file, so it's not executing anything. Which explains why it returns so fast, while you expect it to take a while.
If you want to execute the referred php files, approach it like this:
Include_once( $final );
Instead of opening the contents.
So I asked a similar question earlier and I'm only more confused now, so I'll ask it in a different way...
What I'm trying to do is abstract my php and put the bits of html, used in my validator as error messages, into functions that return the html to the spot where they are needed in the page.
What I have right now is:
<section>
<?php
if($errMsg)
{
errMsg();
}
?>
</section>
<?php
function errMsg()
{
?>
<section>
<p>O crap! There was an error</p>
</section>
<?php
}
?>
But in my previously mentioned question, I was told doing it this way is a 'dirty hack' and its better to use return in situations like this. But to use return I'd need to assign all of the returning html to a var and to do that I would need to put the html in a string. I'd rather avoid putting more than two lines of html in a string because of the pain in the butt number of quotes needed to do so.
So I'm thinking I either use the heredoc syntax or ob_start/ob_get_clean functions. What I'd like to know is.
1 Do I even need to bother with abstracting my code like this?
2 If so, which way is the best practices way to do it? And/Or
3 Should I just give up on web development and go back to pizza delivery? :-\
1: You don't need to, but you can if it's done properly.
2: To do this, i recommend you to use the EOF in your PHP error func, it looks like this :
function errMsg()
{
$error = <<<EOF
<section>
<p>O crap! There was an error</p>
</section>
EOF;
}
I wouldn't return any HTML. Simply return the error message from the function and then build the html in a more appropriate place. For example the inside the template.
Yes definitely, you have no flexibility with the way you are doing it.
You should separate all of your HTML from your PHP ideally, at least functions - the only place it is remotely acceptable is within a view which uses PHP just to display the output of the functions.
Pizza! Just kidding, but there can never be enough pizza!?
Take a look at the Zend framework http://framework.zend.com/manual/en/zend.application.quick-start.html they forward error messages which aren't caught to an error handler, which then uses its own view to render the error.
Or w/o a framework:
try{
//do work here and throw exception on error
}
catch (Exception $e)
{
//do error logging/display error
//or preferably load another class which handles your error and produces output
}
You could just do this:
<?php if($errMgs){ ?>
<section>
<p><?php echo errMsg(); ?></p>
</section>
<?php } ?>
Generally, I try my best not to echo out HTML via PHP. Why? Because if a designer needs to work on my code, I don't want him/her worrying about what HTML my functions are spitting out.
Move the html code into a separate file, error.php. After that you just capture the output:
function errMsg()
{
ob_start();
include '/path/to/error.php';
return ob_get_clean();
}
// ...
echo errMsg();
First off, I agree with the posts above. Don't format, just have the function return the bare error message and if you need to format it appropriately where you want to display it.
Secondly, I always find that it is useful to be able to turn error and testing messages on and off quickly. As the majority of my code is object orientated and I might only want to have messages popping from an object at a time, I normally have something like this in my classes:
class userObject
{
public $history;// = historyObject;
public $userName;
public $userRelation;
public $userCode;
private $mySQLAccessData;
private $isDebug=false;
public function makeHistoryObject($KPI, $KPIType)
{
if($this->isDebug){echo "Having a go at creating ".$this->userName.".<br>";}
$this->history = new historyObject($this->userCode, $KPI, $KPIType);
}
}
I slip a private element in which I leave as false by default. If I need to debug or make changes, I set it to true and all my error/logging messages are neatly displayed on screen. I know that this isn't directly answering your question, but I do find that it is so handy it might be worth it for you when you start. It certainly beats commenting out and then uncommenting potentially dozens of messages. You can leave these outputs in the object without worrying and have them displaying all the detail you need.
If you may at some point have number of errors, then do like this
<?php
$errors = array();
if (!$item = getItem($id)) {
addError("No item $id");
}
if (!updateUser($user, $id)) {
addError("Can not update user");
}
if (!updateItemPicture($id, $picture)) {
addError("Can not add picture to $id");
}
function addError($error) {
global $errors; $errors []= $error;
}
function hasErrors() {
global $errors; return count($errors);
}
function printErrors() {
if (!hasErrors()) return;
print "<ul class='errors'><li>" . join("</li><li>", $errors) . "</li></ul";
}
printErrors();
?>
This is in case you are not using object oriented way. And assuming that all errors are not fatal and caught in try {} catch () {} blocks.
Is it a good or bad practice to authenticate and then just exit() the function or to wrap the whole result of the authentication in an if statement? Example
function foo($uid)
{
$allowed = $auth->checkIfAllowed($uid);
if ($allowed == false) exit();
//continue with senstive code here
}
}
OR
function foo($uid)
{
$allowed = $auth->checkIfAllowed($uid);
if ($allowed == true)
{
// do sensitive stuff
}
}
I would like to take this opportunity to talk about exit; (as others have stated both work, the second is more explicit then the first, and give you the opportunity to send a nice error message to the user). My main beef (I have several with exit;) is that people should stop using it in libraries, i.e. code that can/will be used in other projects... You know how irritating it is to debug those? Throw exceptions, trigger fatal errors, but give me something with a description.
/rant
Your examples are equivalent.
However, it's not usually useful to the end user to just exit the script abruptly. Instead, send your user a useful error message printed in HTML rather than the plain text you would get from a die() call, for example.
function foo($uid)
{
$allowed = $auth->checkIfAllowed($uid);
if ($allowed == false)
{
$errormsg = "You are not allowed to view this page";
}
else
{
//continue with senstive code here
}
}
Later, print the error in HTML, rather than just aborting the script:
<div class='error'><?php echo $errormsg; ?></error>
Either or. I don't think it'll make a difference. It relatively the exact same thing. In programming there are many ways to program things, never on right way in most instances.
They are absolutely the same. The indentation and coding style is the only difference. In both cases the sensitive code won't execute unless the authentication is done successfully.
It's usually better to be expressive in your code though, so I'd recommend the second method.
When I'm developing websites, I use a very (very) simple system of creating pages:
//$_page is, of course, declared above the loop, just as $needed_modules is.
foreach ($needed_modules as $part)
{
global $_page;
if (file_exists($part)) {
$_page . file_get_contents($part);
} else {
//404
}
}
echo $_page;
Now, the problem is that file_get_contents doesn't return anything: not false, not a string, nada (and the file is not empty).
Execution does go inside the if and $part (which corresponds to a filename with relative path) isn't just set, but it actually points to the file.
Why is it that $_page is empty (as opposed to being set, isset($_page) actually evaluates to TRUE)?
Edit: Error-reporting is on full throttle on my server, and the logs show nothing out of the ordinary.
You are not saving the return value of file_get_contents:
$_page . file_get_contents($part);
I think you meant to say:
$_page .= file_get_contents($part);
You're not doing anything with the returned value. Try this:
$_page .= file_get_contents($part);