Not sure if it's global per se, but what I need is a variable that is set from within a model that is dynamically generated when the model gets called. However I need to set a variable that is accessible to multiple views being pulled in through the template to use the same variable.
Its an advertisement ID my clients sponsors have multiple ad spots per page example a 486x 60 and a 160x90 spot. But what I am trying to do is when there ID is pulled at random from the bunch I want all my ad spots to be the same sponsor.
Now I have tried going in my header.php view and defining a variable like
$adsIDvar = $this->modelname->sponsorids() and then in every view I have ad placement just using $varIDvar but it doesnt seem that any of the views inherate the variable. I have tried to find information on this but most people looking for a similar notation need hard coded variables like a site title for example.
I need something that can cross the barrier, and I'd prefer to avoid sessions/cookies as I want to avoid dealing with the whole Cookie thing in the UK as a good half of the viewers of the site are from the UK and I'd rather not have to go through the effort of saying this site uses cookies blah blah accept/decline just for this purpose. Besides, if they decline, that puts a kink in my work.
If you want to import a variable from the global scope, you need to use the global keyword. For example:
class SomeClass {
public function SomeFunction() {
global $adsIDvar; // now it is imported from the global scope
}
}
It's just my opinion but maybe a better approach would be to make a special class just for handling ad ids. I might try something like this:
class AdHelper {
public static $advertiser_id;
public static function getAdvertiserId() {
if (!isset(self::$advertiser_id)) {
self::selectAdvertiserId();
}
return self::$advertiser_id;
}
protected static function selectAdvertiserId() {
self::$advertiser_id = ....; // Implement this however you like, random or whatever
}
}
// you can call it from anywhere like:
$adsIDvar = AdHelper::getAdvertiserId();
Related
I've just started PHP developement and I would like to know a bit more about variables scope.
I know about the scope inside the script. I just want to know, how variables are treated between different users. Let's say I have a class :
class SomeClass {
public static $myVar = 0;
public static function doSomethingToMyVar(){
// $myVar gets manipulated
}
}
NOTE: I know it's an awful design, so it's just for showing an example of my question.
Now my question is: if user A uses the page so that doSomethingToMyVar is called, does user B get modified value of $myVar? I mean, do different users share static variables or PHP gives seperate sets of variables for each user?
In my screenshot below you can see I have a list of functions that run a routine, fairly in-depth routine.
Previously, I have ben repeating this routine in multiple classes, but now I would like to consolidate those multiple classes into one class and execute only one function, by passing a variable into that function to determine the output to return.
I know how to pass the variable into "one" function, but how can I pass the variable ($this_id) into my multiple functions below? Basically, whatever $this_id is from get_output($this_id); I want that same variable value to be carried over into the other $this_id functions. See screenshot...
I searched online and all answers I've seen show how to do this in a non static way, but I'm only familiar with calling things statically, really. I tried the obj way, but couldn't get it to work.
Example, execution...
$header = 'CustomTheme_output';
$header::get_output('header');
(please disregard any lose code, the code is what I have so far from trying multiple ways. private $id and __construct are from the online solutions I have been trying)
Could you please clue me in on how I can correctly achieve this? I would be sooo happy to get rid of all the repetitive code, folders and files I have! - Thanks!
Either you pass it directly into each method call:
public function foo($this_id) {
$this->bar($this_id);
}
Or you make it a class attribute, and simply ACCESS it from the various methods:
public function foo($this_id) {
$this->id = $this_id;
$this->bar();
}
public function bar() {
do_something($this->id);
}
Sorry if I am not using the best jargon, but I have run into an issue I want to solve early before I write too much code. Which of these options below is "better"? And is there a better way of doing this? Someone mentioned to me abstracting my code but another class seems to be the last thing I need. Also I feel like there's something I can do by potentially making my "get" function seen below into a public static function so that I can use it differently. (its not static right now)
Here is my situation:
I have 2 (relevant to this question) classes, DB (database) and Page (for getting my content to display on my website)
the DB class has a query method that prepares and execute my queries
the DB class also has methods for inserting, getting, deleting things from the database.
I now feel that I may not even need my page class because right on the webpage I can just use those DB methods to call my content. (I store all images, content, page title, description in mysql). Is this not a legitimate way to do this? Won't I need to create a new object each time? such as:
$pg_ID = 2;
$title = new DB($pgID);
$title->get('pages', $pgID, $lang); // 3 tables to pull from for each page
$images = new DB($pgID);
$images->get('images', $pgID, $lang);
$structure = new DB($pgID); // I need these tables mostly because my site is in two languages
$images->get('pages_list', $pgID);
I do not like this potential solution just because to me its counter intuitive. Why should I have to create new objects just to reuse a function? However, what I do right now is something I feel is going to get me some hate mail.
$page = new Page();
$page->find('pages', $pgID, $lang);
$page->lookup($pgID);
$page->retrieve('images', $pgID, $lang);
These are 3 separate functions in my Page class that perform very similar things. Find gets my pages content out of the database and returns it as an object. Lookup does basically the same thing but only needs to pass one variable because its only to do with the html structure of each page regardless of which language is being accessed. retrieve gets all images from a table that get shown in a slider with different language descriptions. But as you can see, all three functions do basically the same thing! They query the database. Thanks for the help with this I am literally just getting into this OOP and its driving me insane. Stack has been very helpful and I think I just didn't know how to search for this to find the answer. Feel free to point me to other questions/answers that I may have missed. It was hard for me to think of the keywords to search for.
we may create other classes indeed, but efficiently so. Maybe we can render DB a public state function. I like the idea of creating a database object, pass it as parameter to an other object, which could then format data with the link he just received:
$pg_ID = 2;
$db = new DB($pg_id);
$page = new Page($db,$pg_ID);
// make sure you assign the parameters a private properties in `Page()` ctor.
then, from inside your function, you can call images, titles and structures at will from $this
$title = $this->DB->get('pages', $this->pgID, $lang);
$images = $this->DB->get('images', $this->pgID, $lang);
$structure = $this->DB->get('pages_list', $this->pgID);
and you can those other method as well
$page->find('pages', $this->pgID, $lang);
$page->lookup($this->pgID);
$page->retrieve('images', $this->pgID, $lang);
Now we do not need to create a new object each time we want information from the database.
Now...
the way I access member functions here $this->pgID is better used by defining a getter: $this->pgID(). I like my getter to have the same name as the property. This might not be a very good idea though.
private function pgID() {
return $this->pgID;
}
As for abstract classes..
I did in fact come very lately into thinking abstract classes were quite cool indeed. I've some problem with wording it, having a constant constructor with custom mandatory functions and possible different implementation of classes seems awesome:
abstract class Page {
function __construct($db,$pgID,$lang,$params='') {
$this->db = $db;
$this->pgID = $pgID;
$this->lang = $lang;
$this->init($params);
}
function pgID() {
return $this->pgID;
}
function lang() {
return $this->lang;
}
abstract function init();
abstract function retrieve();
}
class Structure extends Page {
function init($params) {
// some specific to Structure foo here
}
function retrieve($what='pages_list') {
return $this->db->get($what,$this->pgID,$this->lang);
}
}
class Image extends Page {
function init($params) {
// some specific to Image foo here
}
function retrieve($what='images') {
$images = $this->db->get($what,$this->pgID,$this->lang);
// plus some foo to resize each images
return $images;
}
}
ok, hope you're still there! Now we have a Structure and Image class with requisites constructor arguments, generic functions and a custom retrieve function. We could use them that way:
$db = new DB(2);
$template = new Structure($db,2,'fr');
$template->retrieve();
$slideshow = new Image($db,4,'en');
$slideshow->retrieve();
I do hope you do not have to create a new instance of DB if you use a different page id :-)
jokes appart this helps me using classes in a better structured way, as I might have many different classes to represent different parts of a site, but when called from an index all of them will have the same function names, like retrieve() or print(), list()...
I don't want to get into the weeds on a SPECIFIC implementation for you situation, rather I am going to offer some generic guidance.
First off, you shouldn't have to create a separate database object (dbo) for title, images, or structure. Chances are the DSN used for each dbo you are initializing are the exact same, so I would create a singleton dbo which can be shared across multiple objects. For reference take a look at Doctrine's connection manager.
Secondly, I think your objectification could be implemented better. Following most ORMS implementation, you have a Record class and a Table class. The Record class is a specific instance of a Record in your schema, whereas the Table class executes queries against your store which may result in multiple records. These results are then hydrated into an array (of records).
So what I would suggest is something like this (code has not been tested and some of it has been stubbed for brevity):
class PageTable
{
public static function getById($id)
{
// Validate id, if invalid throw exception
$dbo = Database::getConnection();
$stmt = $dbo->prepare('SELECT * FROM page WHERE id = :id');
$stmt->bindParam(array('id' => $id));
$stmt->execute();
$result = $stmt->fetch();
$page = new Page;
// Hydration
$page->setId($result['id']);
$page->setImages($result['images']);
return $page;
}
}
class Page
{
protected $id;
protected $title;
public function setId($id){}
public function getId(){}
}
Hopefully this separation of Record and methods affecting a single, or multiple records makes sense. You should take a look at a DBAL, like Doctrine.
Is this just impossible?
I thought I would clean up some of my code and put db queries in models only where they belong and put all the other code that belongs in controllers in controllers.
Now I keep getting undefined variable errors. Which is not a problem but I'm trying to work out how to call variables between files.
I would simply like the random hash generated at registration .. stored in a variable because that's the variable I use in the anchor for the "click here to activate account" link that is sent to users email.
I also use that same variable in the method that compares the uri hash that's at the end of the URL in their email with the one stored in the database.. in order for user to confirm their account and update "status" in database to 1(activated).
I would really appreciate some advice. I'm enjoying this learning process. Loosing sleep but enjoying it as it make me think logically.
You cannot access a variable if it's in a seperate file, instead you should set it in your class.
class User_model extends Model {
// Declare the foo variable
public $foo = "";
function blah() {
// You can set variable foo this way from any controller/model that includes this model
$this->foo = "dog";
// You can access variable foo this way
echo $this->foo;
}
}
I wonder if anyone can help out here, I'm trying to understand how use an objects properties across multiple non class pages,but I can't seem to be able to get my head around everything i have tried so far.
For example a class called person;
class person {
static $name;
}
but i have a number of different regular pages that want to utilize $name across the board.
I have trying things like this;
pageone.php
include "person.php";
$names = new Person();
echo person::$name;
names::$name='bob';
pagetwo.php
include "person.php";
echo person::$name;
I can work with classes to the extent I'm OK as long as I am creating new instances every page, but how can make the properties of one object available to all, like a shared variable ?
Thanks
Every new instance of a PHP script "forgets" everything done in previous scripts. The usual way of establishing a "storage room" for data across page loads is sessions. A session is essentially a specific ID a user gets when visiting a page. That ID is stored in a cookie, or a GET variable that is appended to every URL. PHP keeps text files in a special directory that can contain session specific data. Every file is named using the session ID.
The PHP manual has a thorough introduction here.
pageone.php
session_start();
$_SESSION["name"] = "Bob",
pagetwo.php
session_start();
echo $_SESSION["name"]; // Bob
Now if you had an instantiated object, you could serialize it, store it in a session variable, and unserialize it back in the 2nd page. I don't think that can be done with static classes though. But this should be a good start.
You need to initialize the static variable inside the class declaration itself:
class Person {
public static $name = 'bob';
}
Or, you need some bootstrapping mechanism, where you inititalize the static variable:
bootstrap.php:
Person::$name = 'bob';
and then in the pages:
// assuming, you preloaded the bootstrap somewhere first
$person = new Person();
echo $person::$name;
edit
Ugh, what was I thinking... the above won't even work. You can't access a static member like that on an instance. Only through a method, like so:
class Person
{
public static $name;
public function getName()
{
return self::$name;
}
}
// assuming, you preloaded the bootstrap somewhere first
$person = new Person();
echo $person->getName();
/end edit
Or as Pekka pointed out, use sessions to keep state.
But more importanty: what is the goal you are trying to achieve? If you want to maintain state of a Person object between different requests, then Pekka's route is the way to go, or alternatively use another persistance storage mechanism, like a DB, File, etc...
Because I presume you don't mean to have every single Person instance named 'bob' do you? I presume you mean to maintain state of a single Person instance.
So, concluding, you probably don't want to use a static member to begin with.