I have read all topics related to this issue, but none of them worked for me.
I am including a class file and before including that I defined a gameid that should be used in class file
here is my code :
$game_id = (int) $_GET['g']; // get id
define("_GAMEID",$game_id);
function show_game(){
global $game_id;
include("includes/class.files.php");
new game_class();
}
// class.files.php
class game_class{
public function getContent() {
global $game_id;
die($game_id);
// die(_GAMEID);
//die($GLOBALS['game_name']);
//die($this->game_id);
}
}
Really funny none of these works for me to get the current id of the game;
when you first defined:
global $game_id; //include this too!!
$game_id = (int) $_GET['g']; // get id
Related
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
Let's say I have a class called product which has 2 properties, pid and quantity.
Now, I want to make a session that will hold an array of this class. Code example:
<?php
public class product{
public $quantity;
public $pid;
public function __construct($pid,$qty){
$this->$pid = $pid;
$this->$quantity = $qty;
}
// some methods ....
}
session_start();
$_SESSION['products'][] = new product(103,10);
$_SESSION['products'][] = new product(87,6);
?>
Few questions about this:
Is my way of declaring the sessions is correct? I haven't typed something like $_SESSION['product'] = new array(); I already added objects to it.
When I will want to read the session product, will I have to import the class product to the page in order to read it and get an access to the quantity and the pid properties?
Code example:
session_start();
echo $_SESSION['products'][0]->$pid; // should echo "103" (according the the code exmaple above)
// OR I will have to do it like this:
require_once 'product.inc.php';
session_start();
echo $_SESSION['products'][0]->$pid; // should echo "103"
3.when I access a public property, do I have to access it like this: $this->$prop_name OR $this -> prop_name (difference is with the $ sign)
if you define a variable like $var = array(); it will wipe the previous array.
sessions are available throughout your domain/sub-domain, so as long as you have called session_start() before you access the session variable you're covered.
when you say public property are you referring to the class or the method? If you want to access the method inside itself to refer to it like $this->myFunction = $object; if you want to access the method outside itself but inside the class you do it using SELF::$object = new myFunction();
see this: When to use self over $this?
and this: http://php.net/manual/en/language.oop5.php
hope this helps.
Is my way of declaring the sessions is correct?
Yes. Once you have executed the session_start() the $_SESSION array will exist and be populated with data if any has been saved into previously.
When I want to read the session product, will I have to import the class product to the page in order to read it and get an access to the quantity and the pid properties?
Yes, if you have methods you need to have the class declared in order to use them.
There is a better way of dehydrating and rehydrating a class. That is serialize() and unserialize(). It takes care of all the public, protected and private data, and it also stores the class name. It does not save the methods of course.
Here is some sample code using your original example as a start point. You can run it in your browser to see the results
file product.class.php
<?php
class product{
public $quantity;
public $pid;
private $a = 99;
protected $b = 88;
public function __construct($p,$q){
$this->pid = $p;
$this->quantity = $q;
}
public function show() {
echo '<pre>SHOW '. $this->pid . '</pre>';
}
}
?>
file tst99.php
require_once( 'product.class.php' );
session_start();
$p1 = new product(103,10);
$p2 = new product(87,6);
unset( $_SESSION['products'] );
$_SESSION['products'][] = serialize($p1);
$_SESSION['products'][] = serialize($p2);
echo 'Dehydrated class'.PHP_EOL;
echo '<pre>' . print_r( $_SESSION, TRUE ) . '</pre>';
?>
file tst99a.php
<?php
session_start();
require_once('product.class.php');
echo '<pre>' . print_r( $_SESSION, TRUE ) . '</pre>';
echo 'Rehydrated class'.PHP_EOL;
$np1 = unserialize($_SESSION['products'][0]);
$np2 = unserialize($_SESSION['products'][1]);
echo '<pre>' . print_r( $np1, TRUE ) . '</pre>';
echo '<pre>' . print_r( $np2, TRUE ) . '</pre>';
$np1->show();
$np2->show();
Run tst99.php first and then tst99a.php to see that the class gets fully rehydrated.
Hi Im stucked with this for 4 days now, i have read massive amount of related articles, but seems nothing is working.
First i will explain my idea, give you some code and then i will tell what i have tried.
Idea. I have 2 separate db tables 'project' and 'pictures'. In project table i put info about projects (id, title, pubdate, template etc.) and i need to assign some pictures to that project so on pictures table i have "project_id" column which is relating those two. In my controller i have function project_picture_proccess($id) this $id is changing according to which project im clicking on and that is how all related pictures are fetched. problem is i cant pass that current project $id to upload model (this is for setting upload path for current project).
This is my controller:
class project extends Admin_Controller{
public function __construct(){
parent::__construct();
$this->load->model('project_m');
$this->load->model('project_pictures_m');
//here is index() function and some other (not related to my problem)
public function project_picture_proccess($id = NULL){
//$id variable is from current project im editing
//and changes according to project id
$this->load->model('upload_m');
if ($id) {
//search for directory in upload path with current project slug name
//and if there isnt any it will create it and add proper rights
$this->project_m->search_and_create_dir($id);
//function get_images is fetching all images that current project has
$this->data['project_images'] = $this->project_m->get_images($id);
//this function is setting upload config (setting upload path
//based on directory created in above)-its working var_dump'ed it
$this->upload_m->set_upload_config($id);
}
if($this->input->post('upload')){
//do_multi_upload works on multiple images just fine
//but i cant make it to get outcome of set_upload_config function
//so i can set upload_path very manualy and everything i upload is in mess
$this->upload_m->do_multi_upload();
//redirection function does not work because it is not getting
//any project_m data and i have lost all project_m related data in my view
//its title of project im editing and its id
redirect('admin/project/project_picture_proccess');
}
$this->data['error'] = array('error' => '');
$this->data['project'] = $this->project_m->get($id);
//function get_images is fetching all unsorted images uploaded in
//the path created above for further proccessing
$this->data['unsorted_img'] = $this->upload_m->get_unsorted();
$this->data['subview'] = 'admin/project/picture_proccess';
$this->load->view('admin/main', $this->data);
}
and here is my model:
class Upload_m extends MY_model{
protected $pic_path;
protected $_primary_filter = 'intval';
protected $_table_name = 'projects';
function Upload_m(){
parent::__construct();
$this->pic_path = realpath(APPPATH . '../img/');
function get_slug($id = NULL){
if($id !=NULL){
$filter = $this->_primary_filter;
$id = $filter($id);
$result = mysql_query('SELECT slug FROM ' . $this->_table_name . ' WHERE id=' . $id . ' limit 1');
$data = mysql_fetch_row($result);
$name = array_shift($data); //array - need to be string
return $name;
}else return;
}
function set_upload_config($id){
if($id == NULL) return;
$slug = $this->get_slug($id);
$upload_config = array(
'allowed_types' => 'jpg|gif|jpeg|png|bmp',
'upload_path' => $this->pic_path . $slug . '/',
'max_size' => 0
);
return $upload_config;
}
function do_multi_upload(){
$this->load->library('upload');
$this->upload->initialize($this->set_upload_config());
if($this->upload->do_multi_upload('userfile')){
var_dump($this->upload->get_multi_upload_data());
return;
}else echo "Error at uploading";
}
Here is what i have tried:
moving if($this->input->post...) method inside if($id) scope and
nothing is passed to view and noting is passed to model
tried like every single solution on stackoverflow: these very common tip was $this->load->model('upload_m', $id) <-
returning null when var_dump($id) tested on function
do_something($id){var_dump($id); die;}
i have made global variables and tried to fetch them by get_class_vars
i have rewrite system/core/libraries/model function to accept variable on do_multi_upload($field<-this is default,
$var=NULL<-optional)
i have tried to put those variables in __construct() function like __construct($var)
i have tried to change name of that $id to $var and put it inside if($this->input->post('upload') && $var === $id) and tried to use $var in model. didnt work this approach
I am so desperate this has taken too too much my time. My goal is to pass $id to upload function to set correct upload path and save data into database url (taken from upload_path), project_id ->taken from passed $id. Any help will be appreciated even if its a suggestion how to change my structure so i could still meet my goals.
I have my main (user visible) file which displays posts, and I need to set-up pagination.
It would be easy if I fetch DB in the same file (but I want to avoid that), that is why I created a seperate (user hidden) file which contains class' which are then called from main file(blog.php):
BLOG.php(simplified):
<?php
require 'core.php';
$posts_b = new Posts_b();
$posts_bx = $posts_b->fetchPosts_b();
foreach($posts_hx as $posts_hy){
echo $posts_hy['title'];
}
?>
core.php(simplified);
class Posts_b extends Core {
public function fetchPosts_b(){
$this->query ("SELECT posts_id, title FROM posts");
//return
return $this->rows();
}
}
This works like a charm, but now I need to do the count within query, which works fine, and which gives me a variable $pages=5 (handled inside class posts_b - in file core.php),
core.php(simplified-with variable);
class Posts_b extends Core {
public function fetchPosts_b(){
$this->query ("SELECT posts_id, title FROM posts");
$pages=5;
//return
return $this->rows();
}
}
Now I need a way to return this variable value to blog.php (the way I return rows())
Please help, anyone,
Thank you...
A function can only have a single return value.
There are ways to get around this though. You can make your return value be an array that contains all of the values you want. For example:
return array("pages"=>$pages, "rows"=>$this->rows());
Then in your code
require 'core.php';
$posts_b = new Posts_b();
$posts_bx = $posts_b->fetchPosts_b();
$pages = $posts_bx["pages"];
foreach($posts_hx["rows"] as $posts_hy){
echo $posts_hy['title'];
}
?>
Or you can adjust a input parameter provided it was supplied as a reference
public function fetchPosts_b(&$numRows){
$this->query ("SELECT posts_id, title FROM posts");
//return
return $this->rows();
}
In your code
require 'core.php';
$posts_b = new Posts_b();
$pages = 0;
$posts_bx = $posts_b->fetchPosts_b(&$pages);
foreach($posts_hx["rows"] as $posts_hy){
echo $posts_hy['title'];
}
?>
Or you can opt to figure out your pagination outside of the fetchPosts_b method.
$posts_bx = $posts_b->fetchPosts_b();
$pages = floor(count($posts_bx)/50);
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();
}