PHP error notices. Should they never be ignored? - php

I'm researching how to better organize my website content with PHP, and I had a question regarding unimportant error notices.
<?php
switch ($_GET['filename']) {
case 'home':
require('src/home.php');
break;
case 'quiz';
require('src/quiz.php');
break;
default:
if ($_GET['filename'] == '') {
include('src/home.php');
} else {
header('HTTP/1.0 404 Not Found');
include('src/page_not_found.php');
}
break;
}
?>
For example here; it's obviously telling me that it's getting undefined when I try to get the filename in the URL parameter. In this context, it's empty, and I'm doing this on purpose to check if there's something in there and if it should be interpreted as one of my other files.
I'm aware that you can add "error_reporting(E_ERROR | E_PARSE);" at the start of the line to hide the notice and the website will work just fine like that, but I was wondering if this is something I should always "fix"?
I was thinking of doing an if condition before the switch case:
if ($_GET['filename'] == ""){
include('src/home.php');
}
But that will throw me a notice as well, since what I am checking is undefined and will trigger the error notice regardless. What should I do?

Tim Lewis answered my question, thank you by the way!; Instead of hoping that a file is there, you can instead use isset().
So, instead of what I made, I would do something like this, to first check if the content is set before doing anything else:
<?php
if (!isset($_GET['filename'])){
include('src/home.php');
} else {
switch ($_GET['filename']) {
case 'home':
require('src/home.php');
break;
case 'quiz';
require('src/quiz.php');
break;
default:
header('HTTP/1.0 404 Not Found');
include('src/page_not_found.php');
break;
}
}
?>

Related

403 error on passing parameters

I have following function in a php file :
function bc_output($vars) {
switch($_GET['a']){
case 'addip':
bc_add_licenses($vars, trim($_GET['current_ip']));
break;
case 'addiprequest':
if(isset($_POST['submitaddip'])) {
display_guidance_text();
bc_add_licenses_request($vars, $_POST);
} else {
display_guidance_text();
bc_get_licenses($vars, '4');
}
break;
default:
display_guidance_text();
bc_get_licenses($vars);
break;
}
}
Now when i go to url such as http://website.com/addon.php?module=b&a=addip it works fine, although for second case i.e http://website.com/addon.php?module=b&a=addiprequest browser throws 403 error..
Can anyone guide me where to proceed from here, i have echoed etc in the function but always 403 error.
Please comment if you need more info.

1. Using switches for multiple url variables

ok say i have these pages,
/admin/admin.php
/admin/blogger.php
inside my main index.php, i have a switch array that runs an 'if exists $page' function, which works fine. all my pages are called from site.com/index.php?page=about, site.com/index.php?page=misc, etc etc.
inside my admin.php page is a php tabbed navigation that uses 4 tabs for my admin sections (blogger/image manager/file manager/quotes manager). it uses a switch of tabfunctions for the 4 pages.
the blogger.php is where i have my switch in question.
now for my question:
instead of having multiple pages for the blog system, "delete.php, add.php, edit.php, etc" and using like 'to delete click (delete.php?id=1) here', i wanted to try and run it all from the blogger page. for example, "site.com/admin.php?page=blogger&act=dp/ep/ap" would get whichever $act is being passed and then using a switch to complete the action.
my PAGE switch works fine, but when i try to call more switches, it doesn't work. I tried using this as my code
if(isset($_SESSION['id'])) {
$act = $_GET['act'];
switch ($act) {
case 'ap':
addPost();
break;
case 'ep':
editPost();
break;
case 'dp':
delPost();
break;
default:
~table setup
~$query, $result
~if / while loops
~echo $row->article_id/title/author/date
echo "Edit"
...
...
...
here is the issue i'm having. the page is correct, the tabindex is correct, then it stops working. i just get a blank page, not the edit page like i should. my editPost function is correct, as i've tested it from the editpost.php?id=1 way, which i am trying to avoid. and yes, my functions are included from here as well.
is the url not being passed right? or is my act switch not set up correctly. maybe setting an isset($_GET['act']) before the switch? i'm at a loss.
thank you.
Do you want to pass multiple actions at once like this?
//test.php?action=add/update/notify
if(isset($_GET['action'])) {
$act = $_GET['action'];
//split actions
$actions = explode('/', $_GET['action']);
foreach( $actions as $action ){
switch ($action) {
case 'add':
echo "add<br />\n";
break;
case 'update':
echo "update<br />\n";
break;
case 'notify':
echo "notify<br />\n";
break;
default:
// default action if no match (runs for every item of $actions array)
break;
}
}
}
site.com/admin.php?page=blogger&act=dp/ep/ap
You can't do that. Specifically act=dp/ep/ap. I would recommend a mix of mod_rewrite and multiple $_GET so then you could do like what WordPress does:
site.com/admin/blog/edit
Mod_rewritten to:
site.com/admin.php?page=blog&act=edit
From there you just have to use $_GET and have just one switch with dependencies.
$page = $_GET['page'];
$action = $_GET['act'];
switch ($page) {
case 'blog':
do($action);
break;
case 'news':
do($action);
break;
case 'users':
do($action);
break;
default: echo 'Try again.';
break;
}
function do($act) {
switch($act) {
case 'delete': confirmDelete();
break;
case 'update': updateConfirm();
break;
}
}
You get the idea.

Optimal way to handle "return"?

I need an advice how to handle function with lots of different return's better.
I have this simple log in function in my class:
public function login($email, $password){
$record = // Go to database and find what we need.
if($record){
// Check pass, $user_match = TRUE;
} else {
return 1; //No such user. Please register!
}
$active = (1 == $record['is_active']) ? TRUE : FALSE;
$verified = (1 == $record['is_verified']) ? TRUE : FALSE;
//User email and password matched:
if($user_match == true){
if($verified === true){
// Start session and insert to db table "online_users"
// Check that user was inserted to table: $confirm = $stmt->rowCount();
if($confirm !== 1){
return 2; //Unexpected technical error. Please try again in a moment.
}
return 0; //0 means that all clear, we good to go.
} else {
return 3; //not verified
}
} else {
return 4; // no match with email and pass, reject!
}
}
The problem is, that now all the time I need to check all return's, something like that:
$log = $user->login($_POST['email'], $_POST['pass']);
if($log === 0) {
//Log in & edirect
} elseif ($log === 1) {
//No such user. Tell to register
} elseif($log === 2){
//technical error, try again
} elseif($log === 3){
//Not verified
} elseif($log === 4){
//wrong password
It's really annoying right now, and imagine if I would need to check like 20 return's? Is there any better way? How to do it more efficient and faster?
Thanks in advance.
You should rethink the purpose of this function and structure the return types accordingly. If the purpose is to log the user in, there can only be one answer: it either worked or it didn't. So the primary return type of the function should be a boolean. How to differentiate between different causes for failure is a different topic.
Option 1: throw exceptions:
try {
if (!$foo->login()) {
echo 'Invalid credentials';
}
} catch (UserNotActiveException $e) {
...
} catch (UserNotValidatedException $e) {
...
}
Not necessarily the most elegant option, since a failed login isn't really an exceptional circumstance.
Option 2: save the error state in the login provider:
if (!$foo->login()) {
echo "You're not logged in because ", $foo->loginError();
}
Whether this is good or not depends on how the class is used otherwise, you may not want to make it too stateful.
Option 3: separate the problem of login from what is the user's state entirely:
if (!$foo->login($user)) {
switch ($foo->currentStatus($user)) {
case $foo::ALL_OK :
echo 'Login credentials invalid';
break;
case $foo::ACCOUNT_INACTIVE :
...
}
}
Option 4: return a status object:
$result = $foo->login();
switch ($result->status) {
case $result::ALL_OK :
...
}
That's essentially what you're doing now, just without the magic numbers.
Using exceptions would be one way to provide clear handling of error code, depending on how this fits into the rest of your application.
As was pointed out by Nanne, you shouldn't use exceptions for flow control: they should only indicate exceptional circumstances. The technical error is clearly an exceptional circumstance and using exceptions for this would be clear and appropriate.
Using exceptions for the rest of it is less clear, but still an option. You could simply throw an exception with different error messages for each failure condition, or different exception classes that have appropriate handlers for the failure conditions.
This is starting to break the semantics of exceptions, depending on how this code fits in with the rest. Being able to call the login function elsewhere without having to worry about it throwing inappropriate exceptions might be useful or necessary, for example.
In the end, there's probably no getting around the need to have explicit checks for each of those failing conditions and returning them inside the function. Again, depending on how flexible this needs to be, you could just return true on a successful login, or an error message on failure (using === to verify that the result is true, not just truthy). Or you could return an object with a success property and an error condition, which at least makes your error handling code a matter of checking the success and handling the error code.
If you need significantly different error handling mechanisms for each failure condition, then returning a constant for each failure case could at least make it clear what's going on in the code. You can then return LOGIN_PASSWORDS_DO_NOT_MATCH instead of a cryptic number, which could then be checked in your error code.
Better use switch statement if you need many if-else statements:
$log = $user->login($_POST['email'], $_POST['pass']);
switch ($log) {
case 1:
break;
case 2:
break;
//etc....
}
To clarify error codes use named constants or static array of name=>code pairs instead of "magic numbers"
static $ERROR_CODES = array(
"WRONG_PASSWORD"=>1,
"WRONG_EMAIL"=>2
);
switch ($log) {
case LoginClass::$ERROR_CODES["WRONG_PASSWORD"]:
break;
case LoginClass::$ERROR_CODES["WRONG_EMAIL"]:
break;
//etc....
}
You can use INI Files
write your bugs in an ini file:
1 = "Error"
2 = " Technical"
3 = "Network"
...
And save it into and ini file. Then use this code:
<?php
$array = parse_ini("er.ini");
echo $array[$log];
?>

php var isset, ?data=menu

I have script where some url leads to index.php?data and the page opens
how can I use that to use the url open an "subpage" like index.php?data=menu or so?
the code I use with the first one is
if(isset($_GET['palvelut'])){ echo "this is a sample"; }
You have the right idea, but allow me to elaborate at little on this. You need to check if $_GET['data'] is set, by doing isset($_GET['data']), and if that is set, checking to see if it has a given value, "menu" in this case. You can do that like this $_GET['data'] == "menu". Putting it all together, you get this:
if (isset($_GET['data']) && $_GET['data'] == "menu") {
/* Menu code goes here */
}
If you would like to have this work for multiple values for data you can do the following:
if (isset($_GET['data'])) {
switch($_GET['data']) {
case "Possible_Value_1" :
/* Code for this condition appears here */
break;
case "Possible_Value_2" :
/* Code for this condition appears here */
break;
/* etc... */
default :
//Just as a precaution...
echo "Invalid 'data' value supplied!";
break;
}
}
Hope that helps.
If I understand your question (which I don't), you've answered it already.
Your URL is: http://www.mydomain.com/index.php?data=something
Your code would be:
if (!isset($_GET['data'])) {
//do something because no data argument was passed
} else {
switch ($_GET['data']) {
case "homepage":
header("location: homepage.php");
die;
break;
case "someotherpage":
header("location: someotherpage.php");
die;
break;
//and so on
}
}
Obviously instead of using a header redirect, you might just require() or include() a file, or do something else entirely.

Not able to GET parameters functioning in include_once

when i call include once without any GET parameters it works but with setting GET parameters on trackinglogs.php nothing happens please suggest me what do to..
my php code is: firstfile.php
include_once('trackinglogs.php?todo=setcookie');
?>
my second file is trackinglogs.php
<?php
$action=$_GET['todo'];
switch($action)
{
case "setcookie":
echo "hi";die();
break;
default:
echo "error"; die();
break;
}
?>
thanks for you precious time
You cannot pass parameters when including like that, include does not make an HTTP request.
The most minimal solution, although I do not recommend it, is to simply set the parameters yourself so that trackinglogs.php finds them:
$_GET['todo'] = 'setcookie';
include_once('trackinglogs.php');
A much better solution would be to put the code that tracks logs inside a function, and call that providing this operating parameters at the same time. So you 'd have something like:
<?php
function track($action) {
switch($action) {
case "setcookie":
echo "hi";die();
break;
default:
echo "error"; die();
break;
}
And you would do:
include_once('trackinglogs.php');
track('setcookie');

Categories