header location doesn't work and still in protect page - php

This code use protect function . to do permission access
I look at address bar found it still in protect page
this is "protect page":
foreach($access_level as $k => $v)
{
// print_r($v); // output 12
protect($v);// call function in loop to get the values of array
}
}
global $v ;
function protect($v){
if($_SESSION['sessionloginid']==true )
{
if( $v ==1)
{header(" location: http://localhost/database/agtdatabase/agt_site/display/display.php");}
}
}

#Mark B above has it right.
Also - Headers are only able to be set if there is no output to the browser when they are run - If you print_r($v), headers are already sent out. Make sure your call to your function is the top possible line, right after session_start().
<?php
session_start();
protect();
/// Other code ///
function protect() {
if($_SESSION['sessionloginid']!==true) { header("Location: http://someplace/index.php"); }
}
Use of header("HTTP/1.1 403 Unauthorized" ); may be a good idea instead of redirecting, if you don't expect a user to see the message unless they are poking around where they shouldn't.
You may also be able to use header("Location: http://someplace/",TRUE,403); to send a 403 code and a redirect at the same time (so any APIs you may use against this site will recognize if they failed to log in correctly).

You're passing $v as an argument to your function, but the function definition has no arguments:
function protect(){
^---no args
PHP has exactly TWO variable scopes: local, and global. The $v you're making global inside the function is probably NOT going to see the $v you defined in the foreach loop above. e.g.
$v = 1; // global scope
function foo() {
$v = 2; // local scope
bar();
}
function bar();
global $v;
echo $v; // outputs 1
}
You should have
function protect($v) {
if ($v == .....) { ... }
}
instead.

Related

How to write PHP codes usable both for http and ajax request?

I have some php codes, and there is a condition which declare type of ajax. Now I want to know, should I write all php codes for each request separately? In other word, should I write all php codes twice (almost repeatedly) for both methods?
if(!empty($_SERVER["HTTP_X_REQUESTED_WITH"]) && strtolower($_SERVER["HTTP_X_REQUESTED_WITH"]) === "xmlhttprequest")
{
// I'm ajax
$arr = array('key1'=>'value1', 'key2'=>'value2');
echo json_encode($arr);
} else {
// I'm not ajax
$arr = array('key1'=>'value1', 'key2'=>'value2');
$_SESSION["arr"] = arr;
header('Location: '.$_SERVER['HTTP_REFERER']); // redirect to previous page
}
So, as you see, I have to write all PHP code twice. One time for regular request and one time for ajax request. In reality there is a lot of codes, Maybe 1000 lines of code that I have two write them again for ajax requests (while they are almost identical). Is this a normal way?
Also I want to know, is there any succinct approach? Actually I like to use a approach which needs to php code just one time for both requests ...!
I would create a class to handle those request and put common code right into a method used by both contexts:
// file: class.handler.php
class contextHandler() {
public function handleHttp() {
$this->handleGeneral();
// What ever has to be done in this context
$_SESSION["arr"] = arr;
header('Location: '.$_SERVER['HTTP_REFERER']);
}
public function handleAjax() {
$this->handleGeneral();
// What ever has to be done in this context
echo json_encode($arr);
}
private function handleGeneral() {
// put common code here
$arr = array('key1'=>'value1', 'key2'=>'value2');
}
}
In your code you could then use that class:
include 'class.handler.php';
$handler = new contextHandler();
if(
!empty($_SERVER["HTTP_X_REQUESTED_WITH"]) &&
strtolower($_SERVER["HTTP_X_REQUESTED_WITH"]) === "xmlhttprequest"
)
{
$handler->handleAjax();
} else {
$handler->handleHttp();
}
This has of course to be adjusted to your concrete needs but offers a nice and clean way of reusing code and generating small and readable code.

PHP $_SESSION variables are not being passed between pages

I am working on a school project where I need my .php pages communicating. I have header.php where I set connection to the database and start the session. In order to start the session only once, I've used this:
if(session_id() == '') {
session_start();
}
PHP version is PHP 5.3.10-1 ubuntu3.18 with Suhosin-Patch (cli)
I am trying to pass some $_SESSION variables between pages, but they keep being unset when I try to use them on a page that doesn't set them.
I see many people have complained about this, but I still can't find the solution.
login-form.php
<?php
if (isset($_SESSION["login-error"])) {
echo '<p>'.$_SESSION["login-error"].'</p>';
}
?>
login.php
$_SESSION["login-error"]= "Username or password incorrect";
There is a code snippet of what is not working for me.
Thanks
You can try this.
In your function file put this
function is_session_started()
{
if ( php_sapi_name() !== 'cli' ) {
if ( version_compare(phpversion(), '5.4.0', '>=') ) {
return session_status() === PHP_SESSION_ACTIVE ? TRUE : FALSE;
} else {
return session_id() === '' ? FALSE : TRUE;
}
}
return FALSE;
}
Then you can run this in every page you want session started
if ( is_session_started() === FALSE ) session_start();
With this I think you should be good to go on starting your session across pages. Next is to ensure you set a session to a value. If you are not sure what is unsetting your sessions you can try var_dump($_SESSION) at different parts of your code so you be sure at what point it resets then know how to deal with it.
The variables are probable not set, because you haven't activate the session variables with session_start().
session_id() == '' is not a correct conditional . Use instead:
if (!isset($_SESSION)) { session_start();}
if you have session started then you can set a session variable
if (!isset($_SESSION["login-error"])) { $_SESSION["login-error"]= "Username or password incorrect";}
Before you call $_SESSION["login-error"], type session_start(), just for testing, to find when the session signal is missing. You said
PHP $_SESSION variables are not being passed between pages
session_start() and SESSION variables needs to be included at the beginning of EVERY page or at the place where SESSION variables are being called (through a common file, bootstrap, config or sth) at the beginning of EVERY page. ie the command to read those data from the server is needed.
Since my header.php file included "connection.php" file, I put
session_start();
at the beginning of connection.php and deleted it from header.php file. Now it works fine. Thanks all for your help!
PHP sessions rely on components of HTTP, like Cookies and GET variables, which are clearly not available when you're calling a script via the CLI. You could try faking entries in the PHP superglobals, but that is wholly inadvisable. Instead, implement a basic cache yourself.
<?php
class MyCache implements ArrayAccess {
protected $cacheDir, $cacheKey, $cacheFile, $cache;
public function __construct($cacheDir, $cacheKey) {
if( ! is_dir($cacheDir) ) { throw new Exception('Cache directory does not exist: '.$cacheDir); }
$this->cacheDir = $cacheDir;
$this->cacheKey = $cacheKey;
$this->cacheFile = $this->cacheDir . md5($this->cacheKey) . '.cache';
// get the cache if there already is one
if( file_exists($this->cacheFile) ) {
$this->cache = unserialize(file_get_contents($this->cacheFile));
} else {
$this->cache = [];
}
}
// save the cache when the object is destructed
public function __destruct() {
file_put_contents($this->cacheFile, serialize($this->cache));
}
// ArrayAccess functions
public function offsetExists($offset) { return isset($this->cache[$offset]); }
public function offsetGet($offset) { return $this->cache[$offset]; }
public function offsetSet($offset, $value) { $this->cache[$offset] = $value; }
public function offsetUnset($offset) { unset($this->cache[$offset]); }
}
$username = exec('whoami');
$c = new MyCache('./cache/', $username);
if( isset($c['foo']) ) {
printf("Foo is: %s\n", $c['foo']);
} else {
$c['foo'] = md5(rand());
printf("Set Foo to %s", $c['foo']);
}
Example runs:
# php cache.php
Set Foo to e4be2bd956fd81f3c78b621c2f4bed47
# php cache.php
Foo is: e4be2bd956fd81f3c78b621c2f4bed47
This is pretty much all PHP's sessions do, except a random cache key is generated [aka PHPSESSID] and is set as a cookie, and the cache directory is session.save_path from php.ini.

PHP SESSION variable troubles

I'm sorry to trouble you, I have tried my best to solve this but I am not sure where I am going wrong and I was wondering if someone out there would be willing to help!
Basically, I am having some issues with $_SESSION variables; I would like for each occasion that a visitor came to the page that they would be shown a different content message.. The below code, when first landing on a page will seem to skip the first "content1", and will display "content2" instead, then "content3" after another revisit. I've put in an unset call, which eventually sends it there, am I not using _SESSIONS correctly?
I'm not sure how the session variable was assigned to 1, for it to land correctly in the if===1 statement without it first returning the original "content1"
if (empty($_SESSION)) {
session_start();
}
if (!isset($_SESSION['content'])) {
$content = "content1";
$_SESSION['content'] = 1;
return $content;
}
elseif ($_SESSION['content'] === 1) {
$content = "content2";
$_SESSION['content'] = 2;
return $content;
}
elseif($_SESSION['content'] === 2) {
$content = "content3";
unset($_SESSION['content']);
return $content;
}
Apologies for babbling or whether this was a simple fix / misunderstanding on my part. It's caused quite a headache!
Many thanks.
-edit-
This is a function that is called from within the same class, it has not gone through a loop anywhere either..
You are only calling session_start(); if the session has not been created.
What about the other times, when it's 1, or 2?
Call session_start(); regardless of your if (empty($_SESSION)) { statement
You should always use the session_start() function. If a session exists, it will continue it, otherwise it will create a new session.
Your code can then be simplified to the following:
// Start/Resume session
session_start();
// Get content
function display_message()
{
if ( ! isset($_SESSION['content']))
{
$_SESSION['content'] = 1;
}
if ($_SESSION['content'] == 1)
{
++$_SESSION['content']; // Increment session value
return 'Content #1';
}
elseif ($_SESSION['content'] == 2)
{
++$_SESSION['content']; // Increment session value
return 'Content #2';
}
elseif ($_SESSION['content'] == 3)
{
unset($_SESSION['content']); // Remove session value
return 'Content #3';
}
}
// Display content
echo display_message();
However, if someone visits your page a fourth time, they will be shown the first message again (because the session value is no longer tracking what they've been shown).
Perhaps this sort of functionality might be handled better with by using a cookie to track this information?

PHP function not working properly (echoing a string, simple)

I created a function to allow me to debug PHP scripts so long as a variable ($debug) is set to 1:
function debug($msg) {
if ($debug == 1) {
echo $msg;
} else {
return false;
}
}
That way, at the top of my script (before the functions.php file is called), I write:
$debug = 1;
to enable debugging, then:
debug("Function executed: " . $data);
at certain points so that I know string values/whatever at that point, with the desired response being the message displayed upon the screen.
However, regardless of what the value of the $debug string is, I never see any echo'd statements.
How can this be achieved?
Debug is not available to your function because it is out of scope. You either:
Need to pass it as a parameter
Use the global keyword to include it in your function (discouraged)
.
function debug($msg, $debug){
if($debug==1){
echo $msg;
} else {
return false;
}
}
or
function debug($msg){
global debug;
if($debug==1){
echo $msg;
} else {
return false;
}
}
It's difficult to say because you provided too few data.
The reason can be that your $debug variable is not known inside a function. Because using globals is not adviced, consider using constants define("DEBUG",1);.
EDIT
I presented within another question how I use a class for doing the same thing as class names are also globally accessed.
The global variable is not accessible to functions until you make it so. Eg:
function debug($msg( {
global $debug;
etc...
PS: Please, don't do this. Find a better way. Really.
$debug is your global variable, so it is not accessible in your function
There is also the possibility to declare a const, (and then just insure the namespace is correct), like this:
const debug = true;
function newPrint($msg) {
if (\debug === true) {
echo $msg;
} else {
return false;
}
}
\newPrint("heey");//will print "heey"
so just dont use a variable, but use a const.

PHP How to implement flash messages

I'm working on a small custom CMS and would like to implement flash messages. I have searched for hours, but I can't find anything that behaves the way I want. And I can't seem to make anything work.
I want to be able to pass a variable (via $_SESSION) to another page and, on that next request, it will be removed. I want to be able to use a keep_flash function, in case I don't want the message to be removed with the next server request.
Can anyone send me in the right direction? I can't really make anything work.
Thanks.
EDIT: Here is some code I am playing with. It sort-of works. When you first visit the page, it sets the $_SESSION and everything is fine. But if you refresh, now it deletes the $_SESSION. If you refresh again, it adds it back...etc. So, if you were to visit the page, refresh, then go to another page the flash message wouldn't be in the $_SESSION. So how can I fix this?
class flash
{
private $current = array();
private $keep = array();
public function __construct()
{
if (isset($_SESSION['flash'])) {
foreach($_SESSION['flash'] as $k=>$v)
{
$this->current[$k] = $v;
}
}
}
public function __destruct()
{
foreach ($this->current as $k=>$v)
{
if (array_key_exists($k,$this->keep) && $this->keep[$k] == $v) {
// keep flash
$_SESSION['flash'][$k] = $v;
} else {
// delete flash
unset($_SESSION['flash'][$k]);
unset($this->current[$k]);
unset($this->keep[$k]);
}
}
}
public function setFlash($key,$value)
{
$_SESSION['flash'][$key] = $value;
}
public function keepFlash($key)
{
$this->keep[$key] = $this->getFlash($key);
}
public function getFlash($key)
{
if (array_key_exists($key,$this->current)) return $this->current[$key];
return null;
}
}
basic idea is to have script always check specific variable in session (usually called 'flash') for content - if not empty display and delete it from session. When message is needed just place is same variable in session and next check would pick it up....
keep_flash in your case would not proceed with delete, or move to other place based on your needs.
for implementation just google it - usually it wrapped in some kind of class - I personally like phpclasses.org or part of framework

Categories