PHP include Problem - php

i'm trying to apply some module system on my web, using get and include, here's some of my code
on my index.php
$section = 'user';
if(isset($_GET) && !empty($_GET) && $_GET !== ''){
$module = $_GET['module'].".php";
load_module($section, $module);
}
load_module function
function load_module($section="", $module=""){
include(SITE_ROOT.DS.$section.DS.'modules'.DS.$module);
}
*i have already define DS as DIRECTORY_SEPARATOR
and i stored few files inside modules folder, the file loads perfectly, my problem is that all the variable i declared on my included page fails to load, here's my code on one of the included file
if($session->is_logged_in()){
$user = User::find_by_id($session->user_id);
$profile = $user->profile();
$company = $user->compro();
$logo = $user->logo();
}else{redirect_to('index.php');}
on my index.php i got this error
Notice: Undefined variable: session in C:\www\starpro\user\modules\edit_company.php on line 3 Fatal error: Call to a member function is_logged_in() on a non-object in C:\www\starpro\user\modules\edit_company.php on line 3
and if i move those variables inside my index.php, i get this message
Notice: Undefined variable: company in C:\www\starpro\user\modules\edit_company.php on line 181 Notice: Trying to get property of non-object in C:\www\starpro\user\modules\edit_company.php on line 181
please some one help me, thank you in advance
Regards
======================================================================
i am using deceze's answer
and modify my user's class by adding a static function like this
public static function load_module($section="", $module="", $user_id=""){
$user = self::find_by_id($user_id);
$profile = $user->profile();
$company = $user->compro();
$logo = $user->logo();
include(SITE_ROOT.DS.$section.DS.'modules'.DS.$module);
}
and then on my index i use this
if(isset($_GET) && !empty($_GET) && $_GET !== ''){
$module = $_GET['module'].".php";
User::load_module($section, $module, $user->id);
}else{
i got it working, but is this a bad practice ??
need advise
thanks much

As has been stated, you are trying to include the code into the middle of the function, making the scope of the included page limited to that function.
One solution would be to have a global array of files to include, then include them at the end of the script. Just add each file to the array, and at the end, loop through it and include them all.
$includeFiles = array();
...
function load_module($section="", $module=""){
// include(SITE_ROOT.DS.$section.DS.'modules'.DS.$module);
global $includeFiles;
$location = SITE_ROOT.DS.$section.DS.'modules'.DS.$module;
array_push($includeFiles, $location);
}
...
foreach( $inludeFiles as $location )
{
include_once($location);
// using include_once so that if the file is added multiple times in the
// document, it only gets included once
}
It is also a massive security risk to include a file based on a parameter in the GET request. You should sanitize that input by either stripping or encoding all symbols which could be used to traverse to another directory and include code you don't want included (so remove any slashes, etc.), or make a whitelist of includable files. If you had an array of sections and modules and their locations you could take an approach which would solve both problems:
$modules = array(
'section1' => array(
'module1' => '/php/modules/module1.php',
'module2' => '/php/frameworks/foo/bar.php'
),
'section2' => array(
'module1' => '/php/modules/baz.php',
'module2' => '/php/modules/quot.php'
)
)
}
$modulesIncluded = array();
...
function load_module($section="", $module="")
global $modulesIncluded;
array_push($modulesIncluded, $section => $module);
}
...
foreach( $modulesIncludes as $section => $module )
{
include_once($modules[$section][$module]);
}
Note: I have not tested any of this code, this is purely theoretical. I would not advise copying this, but using it as a jumping-off place.

Including a file is like putting the contents of the file exactly where the include command is. So, this:
function load_module($section="", $module=""){
include(SITE_ROOT.DS.$section.DS.'modules'.DS.$module);
}
is equivalent to this:
function load_module($section="", $module=""){
if($session->is_logged_in()){
$user = User::find_by_id($session->user_id);
$profile = $user->profile();
$company = $user->compro();
$logo = $user->logo();
}else{redirect_to('index.php');}
}
All your variables are confined to the scope of the function. As soon as the function returns, the variables go out of scope. Also, variables that are not in scope inside the function are not available to the included code.
You'll need to do the include directly without the function.

The include's scope is the same as if the code were in that function.
If you want a variable in this case to be global, assign it to $GLOBALS['varName']

Aside from using globals, you can also use static class methods/properties, e.g.:
/* session.php */
class session {
public static $user_id;
public static $logged_in;
public static function user_id() {
return self::$user_id;
}
public static is_logged_in() {
return self::$logged_in;
}
}
/* foo.php */
class foo {
public static $user;
public static $profile;
public static $company;
public static $logo;
public static function init() {
self::$user = User::find_by_id(Session::user_id());
self::$profile = self::$user->profile();
self::$company = self::$user->compro();
self::$logo = self::$user->logo();
}
}
if (Session::is_logged_in()) {
foo:init();
}

Related

Converting array key and values into single variables

I know that you can use extract() to achieve this however my circumstances are as followed:
I am building a very small basic MVC framework for personal projects and I have this in my controller:
public function index(){
$data = [
'title' => 'Welcome'
];
$this->view('pages/index', $data);
}
As you can see this passes the data array into the view and you can echo it like:
echo $data['title'];
But I want to echo it like echo $title; I know that extract() can do this but that means I have to manually put extract($data); at the top of every page which isnt the end of the world but I was just curious if there was a way it could be done automatically? I have tried to use extract by putting it inside the view function but that did not work. I have also tried to use extract by putting it in the header file that is required_once in index.php (thus making the header file a static header thats always required) but neither has worked so any advice would be great.
Here is the code for the view function as requested:
public function view($view, $data = []){
if(file_exists('../../views/'.$view.'.php')){
require_once '../../views/'.$view.'.php';
} else {
die('View does not exist');
}
}
Simple that is it ,use compact and extract function
index method
public function index(){
$title='Welcome';
$this->view('pages/index', compact('title'));
}
Wiew method
public function view($view, $data = []){
extract($data);
if(file_exists('../../views/'.$view.'.php')){
require_once '../../views/'.$view.'.php';
} else {
die('View does not exist');
}
}
In html
<h1> hello <?php echo $title; ?></h1>
Here is where I went wrong, I put extract in the view method before and it didn't work.
However the advice here was to put it in the view function and I now understand that I put the extract function after require_once '../../views/'.$view.'.php'; I just put extract before that line of code and it is now working!

Use variables for more than one output? [ PHP Functions ]

I'm currently a beginner developer and have just started my first big project whilst I have spare time, What I'm trying to do is basically write variables to a html/tpl document, Which I have currently got working, Here is my code:
private function index(){
$username = 'MyUsername';
$onlineTime = 'MyOnlineTime';
$this->setParams('Username', $username); // $username Will be replaced by database queried results once completed.
}
And here is the setParams function.
function setParams($item1, $item2){
ob_start();
$theme = 'default';
include_once T . '/'.$theme.'/index.php'; // T . is defined at the beginning of the document.
if ((($html = ob_get_clean()) !== false) && (ob_start() === true))
{
echo preg_replace('~{(['.$item1.']*)}~i', ''.$item2.'', $html, 1);
}
}
And here is the coding inside the html/tpl document.
{username} has been online for {onlineTime} Hours
This is probably a very simple code for some of you but as this is my first attempt this is all I can do.
What I would like to do is have it so you can setParams as many times as you want without changing the $variable names like so:
private function index(){
$username = 'MyUsername';
$onlineTime = 'MyOnlineTime';
$this->setParams('Username',$username);
$this->setParams('OnlineTime', $onlineTime);
}
whilst keeping the setParams($item1, $item2)
But as you can imagine this just cuts the code completely. Does anyone know a solution to this problem? I've been searching all day without any real luck.
Thanks In Advance,
Ralph
I think what you need is a class with a static method;
<?php
class Params {
public static $params = array();
public static function setParam($key, $value) {
self::$params[$key] = $value;
}
public static function getParam($key) {
if (isset(self::$params[$key])) {
return self::$params[$key];
}
}
}
// Usage
// Set Username
Params::setParam("username", "JohnDoe");
Params::setParam("password", "12345");
echo Params::getParam("username");
echo Params::getParam("password");

PHP Vars From Included Bootstrap Not Showing Up in View

I have created my own little PHP framework for fun, however, I am having trouble passing variables from bootstrap to the views....
if I put an echo,print_r,var_dump my target variable in the bootstrap, the output is displayed in the browser before the tag... yet the target var in bootstrap.php is not available in the view, it is coming up as "" even though at the top of the page it is being output correctly....
Somethings I noticed from similar questions:
- The target variable is not being over written
- The include target path is correct and the file exists
- The file is only being included one time (include_once is only fired once)
Any ideas are greatly appreciated, I am pulling my hair out over here lol...
Source Code
https://gist.github.com/jeffreyroberts/f330ad4a164adda221aa
If you just want to display your site name, I think you can use a constant like that :
define('SITE_NAME', "Jeff's Site");
And then display it in your index.tpl :
<?php echo SITE_NAME; ?>
Or, you can send your variables to the view by extending a little bit your JLR_Core_Views :
class JLR_Core_Views
{
private $data;
public function loadView($templatePath, $data = array())
{
$this->data = $data;
$templatePath = JLR_ROOT . '/webroot/' . $templateName . '.tpl';
if(file_exists($templatePath)) {
// Yes, I know about the vuln here, this is just an example;
ob_start();
include_once $templatePath;
return ob_get_clean();
}
}
function __get($name)
{
return (isset($this->data[$name]))
? $this->data[$name]
: null;
}
}
Then, you can call your template like that :
$view = new JLR_Core_Views();
$view->loadView("index", array("sitename" => "Jeff's Site"));
And here is your index.tpl :
<?php echo $this->siteName; ?>
Below is another example of what you can do.
First, you create this class in order to store all the variables you want :
<?php
class JLR_Repository {
private static $data = array();
public function set($name, $value) {
self::$data[$name] = $value;
}
public function get($name) {
return (isset(self::$data[$name]))
? self::$data[$name]
: null;
}
}
?>
Then, when you want to store something in it :
JLR_Repository::set("sitename", "Jeff's Site");
And in your index.tpl :
<?php echo JLR_Repository::get("sitename"); ?>
try using the 'global' keyword - http://php.net/manual/en/language.variables.scope.php

Dynamic global array in codeigniter

I want a global array that I can access through controller functions, they can either add or delete any item with particular key. How do I do this? I have made my custom controller 'globals.php' and added it on autoload library.
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
$notification_array = array();
$config['notification'] = $notification_array;
?>
following function on controller should add new item to my array
function add_data(){
array_unshift($this->config->item('notification'), "sample-data");
}
after add_data adds to the global array, whenever following function is called from client, it should give the updated array to the client.
function send_json()
{
header('content-type: application/json');
$target = $this->config->item('notification');
echo json_encode($target);
}
But my client always gets empty array. How can I make this happen? Please help.
Hi take advantage of OOP, like this
// put MY_Controller.php under core directory
class MY_Controller extends CI_Controller{
public $global_array = array('key1'=>'Value one','key2'=>'Value2'):
public function __construct() {
parent::__construct();
}
}
//page controller
class Page extends MY_Controller{
public function __construct() {
parent::__construct();
}
function send_json()
{
header('content-type: application/json');
$target = $this->global_array['key1'];
echo json_encode($target);
}
}
One solution I came up is to use session, its easy to use and its "fast" you need to do some benchmarking.
As I commented on both answers above/below there is no way you get same data in different controllers just because with each request everything is "reset", and to get to different controller you need to at least reload tha page. (note, even AJAX call makes new request)
Note that sessions are limited by size, you have a limit of 4kb (CodeIgniter stores session as Cookie) but wait, there is way around, store them in DB (to allow this go to config file and turn it on $config['sess_use_database'] = TRUE; + create table you will find more here)
Well lets get to the answer itself, as I understand you tried extending all your controllers if no do it and place some code in that core/MY_Controller.php file
as follows:
private function _initJSONSession() { //this function should be run in MY_Controller construct() after succesful login, $this->_initJSONSession(); //ignore return values
$json_session_data = $this->session->userdata('json');
if (empty($json_session_data )) {
$json_session_data['json'] = array(); //your default array if no session json exists,
//you can also have an array inside if you like
$this->session->set_userdata($ses_data);
return TRUE; //returns TRUE so you know session is created
}
return FALSE; //returns FALSE so you know session is already created
}
you also need these few functions they are self explainatory, all of them are public so you are free to use them in any controller that is extended by MY_Controller.php, like this
$this->_existsSession('json');
public function _existsSession( $session_name ) {
$ses_data = $this->session->userdata( $session_name );
if (empty( $ses_data )) return FALSE;
return TRUE;
}
public function _clearSession($session_name) {
$this->session->unset_userdata($session_name);
}
public function _loadSession($session_name) {
return (($this->_existsSession( $session_name )) ? $this->session->userdata($session_name) : FALSE );
}
the most interesting function is _loadSession(), its kind of self explainatory it took me a while to fully understand session itself, well in a few words you need to get (load) data that are in session already, do something with it ([CRUD] like add new data, or delete some) and than put back (REWRITE) all data in the same session.
Lets go to the example:
keep in mind that session is like 2d array (I work with 4+5d arrays myself)
$session['session_name'] = 'value';
$session['json'] = array('id' => '1', 'name' => 'asok', 'some_array' => array('array_in_array' => array()), 'etcetera' => '...');
so to write new (rewrite) thing in session you use
{
$session_name = 'json';
$session_data[$session_name] = $this->_loadSession($session_name);
//manipulate with array as you wish here, keep in mind that your variable is
$session_data[$session_name]['id'] = '2'; // also keep in mind all session variables are (string) type even (boolean) TRUE translates to '1'
//or create new index
$session_data[$session_name]['new_index'] = FALSE; // this retypes to (string) '0'
//now put session in place
$this->session->set_userdata($session_data);
}
if you like to use your own function add_data() you need to do this
well you need to pass some data to it first add_data($arr = array(), $data = ''){}
eg: array_unshift( $arr, $data );
{
//your default array that is set to _initJSONSession() is just pure empty array();
$session_name = 'json';
$session_data[$session_name] = $this->_loadSession( $session_name );
// to demonstrate I use native PHP function instead of yours add_data()
array_unshift( $session_data[$session_name], 'sample-data' );
$this->session->set_userdata( $session_data );
unset( $session_data );
}
That is it.
You can add a "global" array per controller.
At the top of your controller:
public $notification_array = array();
Then to access it inside of different functions you would use:
$this->notification_array;
So if you want to add items to it, you could do:
$this->notification_array['notification'] = "Something";
$this->notification_array['another'] = "Something Else";

How do I go about loading vars from an include() within a function()?

I'm trying to get some variables from a .php file. I call a function which has an included file in it that has the vars I want but it won't return any. Within the function I can view the variables values, but not outside the function.
//MODULE INCLUDE
function moduleInclude($mid) {
$query = "SELECT file,type FROM sh_module WHERE mid = '{$mid}'";
$exe = mysql_query($query);
$row = mysql_fetch_array($exe);
$folder = moduleFolder($row['type']);
$output = include("../includes/modules/".$folder."/".$row['file']);
return $output;
}
//Load the vars
moduleInclude($mod_ship);
$ship_meth = $MODULE_title_client;
//THE ^^^^ MODULE_title_client never returns anything :(
include does not return the content of file include just put the code of that file at the place where the file is included.
And the variables declared in the files are available after the include statement. but as you are trying to access them outside the function the variable will not be accessible as they are now function scope.
You could update your code to include that file from outside the function.
function moduleInclude($mid) {
$query = "SELECT file,type FROM sh_module WHERE mid = '{$mid}'";
$exe = mysql_query($query);
$row = mysql_fetch_array($exe);
$folder = moduleFolder($row['type']);
return "../includes/modules/".$folder."/".$row['file'];
}
//Load the vars
$include_path=moduleInclude($mod_ship);
include $include_path;
$ship_meth = $MODULE_title_client;
I think you can use something like this:
//MODULE INCLUDE
function moduleInclude($mid) {
$query = "SELECT file,type FROM sh_module WHERE mid = '{$mid}'";
$exe = mysql_query($query);
$row = mysql_fetch_array($exe);
$folder = moduleFolder($row['type']);
include("../includes/modules/".$folder."/".$row['file']);
return get_defined_vars();
}
//Load the vars from include file into array
$module_vars=moduleInclude($mod_ship);
//Use the desired variable
$ship_meth = $module_vars['MODULE_title_client'];
if I understood you correctly. It is really ugly and I suggest you learn more about variable scopes to make this code better as including in a function is almost always the wrong way to go. I think we need to know what hapens inside your include file "../includes/modules/".$folder."/".$row['file'] to help you better.
Just return an object at the end of your include file:
$foo = 1;
$bar = 2;
return array('foo' => $foo, 'bar' => $bar)
Then, include will return the array returned in the module.

Categories