PHP Function 'return' not returning - php

This is a bit of an oddity for me. PHP is my forte, and I can normally figure out any issue I encounter.
I have a custom framework that I have been using for years. I have taken it upon myself to rewrite it, and I'm doing everything essentially the same that I was before. The problem lies in the following construct:
function ModPages_GetPage() {
$page = ModPages_GetPageByName($_GET['page_name']);
if($page != false) {
include(TPL_DIR.'pages/pages.view.php');
} else {
ErrorMessage('Invalid Page', 'The selected page could not be found.');
}
}
function ModPages_GetPageByName($page_name = null) {
$db = new Database;
$query = '
SELECT *
FROM pages
WHERE page_name = "'.CleanStr($page_name).'"
AND page_enabled = "yes"
LIMIT 1
';
$page = $db->GetRow($query);
return $page;
}
This code is being called with 'home' for the value of $_GET['page_name']. The call to ModPages_GetPageByName() is working fine, but the value of $page in ModPages_GetPage() isn't getting set. Matter of fact, any debugging statements thrown in after that call are failing to display anything.
I have display_errors set to on, and error_reporting set to E_ALL. I get a couple notices from my Database class, but that's it.
Running the script at a shell fails to produce any errors. When using strace, I do see the process spits out an 'exit_group(255)'.
This one has me quite baffled. I could sure use some direction on this.

I would think it's your query, shouldn't you just return the page name instead of star? as star (*) would return an array which is probably being passed back as the value? just my guess.
$query = '
SELECT *
FROM pages
WHERE page_name = "'.CleanStr($page_name).'"
AND page_enabled = "yes"
LIMIT 1
';
if you do a print_r on the $page return I would think it should be an array
$page = $db->GetRow($query);
echo "Page:<pre>".print_r($page,true)."</pre><br />\n";
Then maybe return something like this
return $page['page_name_field'];

ok before we get to a solution can we first make sure that before setting the $page variable, first just echo $_GET['page_name'] to see if there is a value being received.
PK

Does your script stop right after your database call, or just doesn't display any output?
If the first is true, then it looks like a fatal error. With E_ALL, it should be displayed, are you sure both display_errors and error_reporting are as you say at that point, and that the GetRow function doesn't alter them in any way? If so, maybe there's something in the Apache error log (PHP errors are sometimes logged there).
If the latter is true I'm thinking about an exception being thrown in a method that is being called, and caught in a higher level function. To check this you can put the database call (ie: the point where things go wrong) inside a try/catch block and see if you reach the catch block.

I would try following:
replace $_GET with $_REQUEST (maybe your form is using POST?)
do a print_r to check contents of your variables.
use mysql_error to view any errors, or print your mysql query in your browser, copy/paste it in phpmyadmin, is it returning anything? error.. data?
something similar happend to me once, my framework was encoded in ANSI and my calling php file was UTF8+BOM... I changed everything to UTF8+BOM and it worked.
try also different browser, I know it might not be a browser problem, but it might be that your script is cached somewhere.
are you using some caching? like eaccelerator?

Are those functions in a class? If so, you will need $page = $this->ModPages_GetPageByName().
Also I would echo out the argument and the sql statment in ModPages_GetPageByName(). This way you can verify that it isn't a SQL error.

I can't say for sure why your code isn't working, but I can make some suggestions that might help in locating the error.
The first thing I notice is you don't check that $db actually contains a valid database. I don't know the details of your Database object but I'm assuming there's some mechanism in there for checking if it's actually connected to the database. You should use that to determine if the database is connected before running queries on it.
$db = new Database ();
if ($db -> isConnected ())
{
$query = 'SELECT * (etc etc etc)';
// ...
}
else
{
// Put some kind of DB connection error notification or throw an exception here
}
Just on a stylistic note, you don't need to store the results of your DB lookup before returning it, unless you're planning on doing some processing on the result before returning it. You can just return the lookup directly. Of course that's just a stylistic choice, but it saves a line or two :)
return ($db->GetRow($query));
After you run your getpage function, I'd strongly recommend var_dump()ing the result. Even if your function returned NULL, you'll still see this in the var_dump. If in doubt, dump it out :). I'd also recommend installing xdebug to make the var_dump output more readable.
$page = ModPages_GetPageByName($_GET['page_name']);
var_dump ($page);
I would also strongly recommending var_dumping your query before you execute just to make absolutely sure that you're running the query you think you're running. Copy and paste the outputted query into sqlyog or phpmyadmin or whatever you use for interactive access to your database and make sure it returns what you think it should return.
Other things to check, is the page you're trying to return actually set page_enabled='yes'? Does the page_enabled column actually store the value as 'yes', or is it a bool or an integer or something else? Is magic quotes enabled or disabled? If they're in one state when you think they're in the other they can cause confusion. Are errors actually being reported to the browser? Add a line at the top of your script that's guaranteed to fail just to make sure, like an attempted foreach on an integer. If you don't see an error, then maybe error reporting isn't configured properly. I know those are obvious questions but I also know how easy it is to overlook the obvious if you're not getting what you expect out of a query.

Are you sure $page is not set, or is it just that your debug instructions don't print anything? Try logging to a file or a database instead; maybe your code triggered output buffering or something like that.
Also, you are calling ModPages_GetPageByName before declaring it. That is usually okay, but might not be in special circumstances (e.g. when the code is wrapped in an if block). Try swapping the two.
Also, check your environment and disable opcode caching and other possible error sources. APC for example can call the old version of the script long after you changed the PHP file.

While some of you have put extra effort into responding to this, nobody has been able to see the full picture, even given the details I have provided. I have been unable to trace the issue back to its source, but have moved on to a different project.

Related

PHP Error handler triggers when using die in outputbuffer context

im developing my PHP framework and at the moment im stuck with a strange behaviour in my error-dispatching page.
The page itself is beautiful, it catches and lists all error using a custom error-handler registered with "set_error_handler()" and can print the line, file, invoked variables and such. It even triggers multiple errors perfectly (except for fatal or syntax-errors which causes the script to hold) but still the dispatches the fatal or even syntax error in this case and even shows me, even when its a null-pointer in a template where the error is located which is beautiful and works awesome.
This system works "using set_error_handler"! The entire output (rendering html /php templates) is realised using "ob_start" and "ob_get_clean" - outputbuffer context.
Next I check if the error-handler catched any errors (will be written in an array in the error-handler's class) and if there are errors and error-display is enabled (developer mode = on) the error-dispatcher page will be displayed instead of the page's content.
However since I implemented that I have one strange behaviour which I do not want:
Whenever I use die() inside of outputbuffer context ((ob_start() ... ob_get_clean()) ) The registered error-handler method is called with an empty error-list displayed and even error_get_last() is empty, but still he triggers that damn function.
This is very disturbing as you cant use die to hold the script to test the output of certain variables which is disturbing in development and seems to be an unusual behaviour to me.
I think posting my entire code is making the thing a little bit too complicated for you to understand thatswhy I leave a little draft explaining the situation, its basically same as it looks in my classes:
//index.php
$errorList = array();
function myErrorHandler($errorType, $errorString, $errorFile, $errorLine, array $errorContext) {
global $errorList;
$errorList[] = $errorString;
}
set_error_handler("myErrorHandler");
//Here my classses and entire rest of framework is loaded...()
//Initialise output
$output = "";
//This method parses templates, it remotely close works like that...
function includeTemplate($templatePath) {
global $output;
ob_start("myErrorHandler");
include($templatePath);
$output .= ob_get_clean(); //Attach to output
}
//This method is called at the very end, it flushes the output, wether by displaying error-dispatcher or page content to be shown.
function flush() {
global $output;
if(count($errorList) > 0) {
echo implode("<br />", $errorList);
} else {
echo $output;
}
}
//Template file: registerTemplate.php
<div class="container">
<Some template output here, doesnt matter if an error occured...>
<?php die($var); ?> //<- Error rised -> Entering "myErrorHandler()" -> but why????
</div>
-> This die() above would rise an error because registerTemplate.php was somewhen parsed using includeTemplate("reigsterTemplate"); which is as located within an ob_start() context. It does not matter if an error occured before or not or even if I just place die("!"); without any invoked variable, it will riase an error.
If I put the die() before or after the include_template context, in upper scope it works as usual and the error_handler does not trigger, as it should work.
Can anyone tell me why this is happening? Thanks alot!
(Important: again this code is not realistic I know its just a draft from how the things look like very barely, dont bother with that giving me hints that this is a bad way to do things. The entire thing is perfectly object oriented and very well structured. I just made this little draft to make you guys understand in what order the methods are called and how my problem comes up because posting my code would waste me and you alot of time as it would be too huge and complex here).

Monitor a PHP variable for change in value

I am actually trying to monitor a PHP variable (may be as a separate thread but not possible in PHP) and fire a PHP function whenever the value of the variable changes.
eg: lets take a variable $_GLOBALS['foo']=1;
if at any point in the code, the value of $_GLOBALS['foo'] changes to something else, i want to fire a PHP function immediately.
The variable can be anywhere inside a loop or in a function,etc.
Why i want this: I have a variable which stores the last error occured as a text. If the value of the variable changes from "" to something else, i want to trigger an error. My LOGIC may seem a bit strange but this is what i would like to do.
Thanx in advance.
Edit: I tried: How to use monitors in PHP? and How can one use multi threading in PHP applications but does not seem to solve the problem.
The Code (Thought this could solve some of your doubts on my question):
public function addtag($tagarray,$uid,$tagtype="1")
{
$dbobj=new dboperations();
$uiobj=new uifriend();
$tagid=$uiobj->randomstring(30,DB_SOCIAL,SOCIAL_TAG,tag_tagid);
$c=0;
foreach($tagarray as $tags)
{
$c++;
$tagname=$tags["tagname"];
$taguid=$tags["tagid"];
$dbobj->dbinsert("INSERT INTO ".SOCIAL_TAG." (".tag_tagid.",".tag_fuid.",".tag_tuid.",".tag_tagname.",".tag_tagtype.") VALUES
('$tagid','$uid','$taguid','$tagname','$tagtype')",DB_SOCIAL);
}
if($c==0)
{
$lasterror="No tags were added";return "";
}
else
{
return $tagid;
}
}
Here, if i call a error handling function instead of monitoring the variable, it wont be advisable in my case since the error handling function may do any operation like give alert and redirect to a page or any similar operation.
I asked this question cause, i thought what if the script does not reach the line
return "";
It would affect the project's workflow. Thats what i am worried about.
And the variable i was talking about is $lasterror and i have many functions like this where $lasterror is used.
I saw this, so I built this:
https://github.com/leedavis81/vent
Should solve your problem.
There is no built-in way to do this in PHP, and there's no easy way to add it. It doesn't really feel right for the way the language works anyway.
Instead of setting a variable, you could build a custom function that handles the error - or use PHP's built-in error handling functionality using a custom error handler.
Another error handling method which comes close to what you want to do (I think) is exceptions.

In php, does "return false" do anything after echo statement?

When I display an error message in php, I usually do it like this,
if($query){
// Success code
}else{
// Error message
$error_msg = "An error occurred.";
return false;
}
and I echo $error_msg variable in the front-end html page.
I am just wondering if that return false after the variable actually does anything, or is it just pointless to put it there?
I am trying to optimize my code and just wanted to make sure! Thanks a lot in advance!
Yes, it tells the function to stop executing, and to return a value "false". So it does something. Whether or not is does something USEFUL depends on your programming.
If you have no executable lines after the echo, and the function is not required to return a value, then it won't actually do anything useful.
If does make it clearer to readers that "this is a stop/failure point" though. And one day you might want to actually trap if it worked or failed - so leaving it in makes it clearer. You also may extend the function without thinking and need to retro-fit the returns - again, leaving it in makes it easier.
On the converse, there is also the old programming style from C / Assembler days that you only have one entry and one exit point for all functions to help with garbage collection. Not a requirement with PHP, but that style does make it nice and neat. In this case, set the return value (if required) and return at the end.
So, go with which suits your style - but think ahead. Making everything pristine and minamlistic (i.e. dropping the line as you don't strictly need it) may not always be the best approach.
The point of the return false is so that you can easily test a function to see if it has worked - without needing to go into any potential error messages and the like.
A function that returns false for a fail can be used in the following manner:
if(someFunction($var))
{
do stuff for function working...
}
else
{
// function failed. Do other stuff.
}
It is also intuitive that a function returns false when it fails. It can be further used like this:
$foo=someFunction($var);
if($foo)
{
again, function has worked.
}//... etc
While the same function returning The function has failed could not be used in tis intuitive manner.

Passing data from one php page to another is not working - why?

Frustrated php novice here...
I'm trying to pass a "type" value of either billto or shipto from ab.php to abp.php.
ab.php snippet:
<?php
echo '<a href="' . tep_href_link(FILENAME_ABP, 'edit=' . $bill_address['address_book_id'] . '&type=billto', 'SSL') . '">' .
tep_image_button('small_edit.gif', SMALL_IMAGE_BUTTON_EDIT) .
'</a>';
?>
This does add the &type=billto to the end of the url. It looks like this:
www.mydomain.com/abp.php?edit=408&type=billto&id=4a6524d
abp.php snippet:
if ($HTTP_GET_VARS['type'] == 'billto') {
then it does a db update...
The if returns false though (from what I can tell) because the update is not performed.
I've also tried $_GET instead of $HTTP_GET_VARS.
Because the code in abp.php isn't executed until after the user clicks a button, I can't use echos to check the value, but I can see the type in the url, so I'm not sure why it's not executing.
Could really use some direction... whether it's what I need to change, or even just suggestions on how to troubleshoot it further. I'm in the middle of a huge learning curve right now. Thanks!!!
edit:
Sorry, I just realized I left out that after the db update the user goes back to ab.php. So the whole workflow is this:
User goes to ab.php.
User clicks link to go to abp.php.
User changes data on abp.php.
User clicks button on abp.php.
Update to db is executed and user is sent back to ab.php.
Because the code in abp.php isn't executed until after the user clicks a button, I can't use echos to check the valueWhy not?
echo '<pre>Debug: $_GET=', htmlspecialchars(var_export($_GET, true)), "</pre>\n";
echo '<pre>Debug: billto===$_GET[type] = ', 'billto'===$_GET['type'] ? 'true':'false', "</pre>\n";
if ( 'billto'===$_GET['type'] ) {
...
edit: You might also be interested in netbeans and its php module:
"Debug PHP code using Xdebug: You can inspect local variables, set watches, set breakpoints, and evaluate code live. Navigate to declarations, types and files using Go To shortcuts and hypertext links."
try something like this
if ($_GET['type'] == 'billto') {
die("got to here, type must == billto");
this will prove that your if statement is working or not,
it may be that the update part is not working
Before the if statement - try
var_dump($_GET);
And make sure the 'billto' is contained within the $_GET array. Of course, if you have got the debuger setup, you should be able to watch the value of the $_GET array
or try:
var_dump($_REQUEST);
Check the URL of the second page, is it in the correct form? From the code snippet you post, I don't know if there would be a ? after the question mark. Also try to disable the redirect to see if your code is working as it should.
One other thing is you may want to put the new url in a variable first, then put that into the link HTML. It's less efficient, but makes the code easier to read and debug.
Try turning on error reporting, place this at the start of your php script
error_reporting ( E_ALL | E_STRICT)
PHP is very tolerant of typos and accessing subscripts in an array that does not exist; by enforcing strict and reporting all errors you would be able to catch those cases.
If you can't see the output, try this:
function log_error($no,$msg,$file,$line)
{
$errorMessage = "Error no $no: $msg in $file at line number $line";
file_put_contents("errors_paypal.txt",$errorMessage."\n\n",FILE_APPEND);
}
set_error_handler('log_error');
You may have to set some file permissions for the log file to be written to.
Of course, you can get Netbeans and its debugging module too.

Can't get memcache to return value

I've taken a bit of a memcache script that i've used previously without issue, but on the new page, I don't get any response.
the memcache is in a function which is included from another page.
what I do is put the md5 hash the mysql query and store that as the key for the memcached data. if the key isn't in memcache, then I go, create the data, put it into memcache and return it.
I think the code is fairly simple. Here are the important bits (it's a large page creating the output, so you don't need all that, though the 'return' I think is important as I fear that might be where I'm screwing up.
I call the function with
$outList.= outData($getList);
where $getList is a mysql query
The $outList function is
<?php
#$memcache = new Memcache;
#$memcache->connect("localhost",11211);
function outData($getList)
{
$memVal = #$memcache->get(MD5($getList));
if($memVal=='')
{
$results=mysql_query($getList)or die(mysql_error());
// then I do a bunch of stuff with the data
#$memcache->set(MD5($getList), $memVal, false, 60000);
}
return $memVal;
}
I can display all the stuff to create $memVal, but i suspect the error is in the if line, but the same code is used on another page without issues.
Anything look wrong with this?
with all those #'s suppressing errors, there's no way to know what is failing.
I ran it - sans the #'s and the answer popped right up though - on the line:
$memVal = #$memcache->get(MD5($getList));
#Notice: Undefined variable: memcache in /home/topbit/736160.php on line 9
Where does it get the variable $memcache ? It's not passed into the function.
The problem is scope. When in a function, variables in global scope do not automatically get passed on, you will have to add them as parameters to the function.
function outData($memcache, $getList)

Categories