Forum Moderators: coopster

Message Too Old, No Replies

Defining dynamic PHP class instead of static values

         

JAB Creations

6:01 am on Dec 7, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I have had a bit of help from a friend though I'm now stuck in limbo trying to get this code to work!

So I've been trying to break in to classes. I want to set a variable once and never have to deal with it again (by using the variable through out all of my PHP code). I've hit a few snags...mostly because the example code I've seen is anything but useful!

I had this working when I statically set the $audio variable (which is referenced as $setting->get('audio'))...but I don't want static! So I commented that out for reference and added some conditional code to determine what the correct value should be. Then well, I started getting a lot of errors!

First I can't use private inside of {}...why the heck not? So I decided to create a temporary variable (feels like a waste of time to me) and then assign the $audio variable to equal the value of $thisaudio. It still did not take! So what the heck is going on and how do I get to where I want to be with the code?

- John

class setting {
//private $audio = 0;

function foo()
{
if ($_GET['audio'] == "0") {$thisaudio = 0; setcookie('audio','0',time()+2592000,'/');}
else if ($_GET['audio'] == "1") {$thisaudio = 1; setcookie('audio','1',time()+2592000,'/');}
else if ($_GET['audio'] == "2") {$thisaudio = 2; setcookie('audio','2',time()+2592000,'/');}
else if ($_COOKIE['audio'] == "0") {$thisaudio = 0; setcookie('audio','1',time()+2592000,'/');}
else if ($_COOKIE['audio'] == "1") {$thisaudio = 1; setcookie('audio','1',time()+2592000,'/');}
else if ($_COOKIE['audio'] == "2") {$thisaudio = 2; setcookie('audio','2',time()+2592000,'/');}
private $audio = $thisaudio;
} //foo()

private $ajax = true;
public function get($item){
return $this->$item;
}
}
//then call it like this
$setting = new setting();
$setting->get('audio');

coopster

4:51 pm on Dec 7, 2007 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



The public/private/protected member (variable) definitions occur outside the methods (functions) so they can be referred to throughout the class. So, you would write it something as follows ...
class setting { 
// Put your member definitions up top here ...
private $audio = 0;
private $ajax = true;
function foo()
{
if ($_GET['audio'] == "0") {$thisaudio = 0; setcookie('audio','0',time()+2592000,'/');}
else if ($_GET['audio'] == "1") {$thisaudio = 1; setcookie('audio','1',time()+2592000,'/');}
else if ($_GET['audio'] == "2") {$thisaudio = 2; setcookie('audio','2',time()+2592000,'/');}
else if ($_COOKIE['audio'] == "0") {$thisaudio = 0; setcookie('audio','1',time()+2592000,'/');}
else if ($_COOKIE['audio'] == "1") {$thisaudio = 1; setcookie('audio','1',time()+2592000,'/');}
else if ($_COOKIE['audio'] == "2") {$thisaudio = 2; setcookie('audio','2',time()+2592000,'/');}
$this->audio = $thisaudio;
} //foo()
public function get($item){
return $this->$item;
}
}
//then call it like this
$setting = new setting();
$setting->foo();
print $setting->get('audio');

I threw in the foo() method call as it seems you may have wanted to modify the initial setting for your 'audio' item. If you want to call the foo() method automatically upon your new class instance, you can either name your constructor the same as the class itself (PHP4), or in PHP you can define a __construct() method.

JAB Creations

7:17 pm on Dec 7, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Thanks a lot for helping me out to get that to work!

I have to make a criticism of PHP though: why must we bother wasting CPU load to set static values when we're going to define them again any way? It makes absolutely no sense.

Thanks again! Below is a slight revision and a second file to show future thread viewers how the variables can now be used across files, the big reason for doing this. :)

- John

test.php

<?php
class setting {
// Put your member definitions up top here ...
private $audio = 0;
private $dhtmleffects = 0;
function foo()
{
if ($_GET['audio'] == "0") {$trueaudio = 0; setcookie('audio','0',time()+2592000,'/');}
else if ($_GET['audio'] == "1") {$trueaudio = 1; setcookie('audio','1',time()+2592000,'/');}
else if ($_GET['audio'] == "2") {$trueaudio = 2; setcookie('audio','2',time()+2592000,'/');}
else if ($_COOKIE['audio'] == "0") {$trueaudio = 0; setcookie('audio','1',time()+2592000,'/');}
else if ($_COOKIE['audio'] == "1") {$trueaudio = 1; setcookie('audio','1',time()+2592000,'/');}
else if ($_COOKIE['audio'] == "2") {$trueaudio = 2; setcookie('audio','2',time()+2592000,'/');}
if ($_GET['dhtmleffects'] == "0") {$truedhtmleffects = 0; setcookie('dhtmleffects','0',time()+2592000,'/');}
else if ($_GET['dhtmleffects'] == "1") {$truedhtmleffects = 1; setcookie('dhtmleffects','1',time()+2592000,'/');}
else if ($_GET['dhtmleffects'] == "2") {$truedhtmleffects = 2; setcookie('dhtmleffects','2',time()+2592000,'/');}
else if ($_COOKIE['dhtmleffects'] == "0") {$truedhtmleffects = 0; setcookie('dhtmleffects','1',time()+2592000,'/');}
else if ($_COOKIE['dhtmleffects'] == "1") {$truedhtmleffects = 1; setcookie('dhtmleffects','1',time()+2592000,'/');}
else if ($_COOKIE['dhtmleffects'] == "2") {$truedhtmleffects = 2; setcookie('dhtmleffects','2',time()+2592000,'/');}
$this->audio = $trueaudio;
} //foo()

public function get($item){
return $this->$item;
}
} //class setting

//then call it like this
$setting = new setting();
$setting->foo();
//echo $setting->get('audio');
?>

test2.php

<?php
include("test.php");
echo 'audio = '.$setting->get('audio');
echo '<br /><br />';
echo 'dhtmleffects = '.$setting->get('dhtmleffects');
?>

coopster

4:10 pm on Dec 11, 2007 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



why must we bother wasting CPU load to set static values when we're going to define them again any way?

You don't have to set an initial value. You can just do a plain old declaration and PHP will store NULL as it's default value.

class setting { 
// Put your member definitions up top here ...
private $audio;
private $ajax;
.
.
.
}
//then call it like this
$setting = new setting();
print '<pre>';
var_dump($setting);
print '</pre>';
// Outputs:
object(setting)#1 (2) {
["audio:private"]=>
NULL
["ajax:private"]=>
NULL
}

JAB Creations

11:43 pm on Dec 11, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



This is mostly a code dump from what a friend had helped me with and some modifications afterwards though I've been busy with other things of late. Still here is what I have and it works brilliantly with other files.

- John

class settings {

private $audio;
private $dhtmleffects;

public function set($name,$value){
$this->$name = $value;
}

public function get($name){
return $this->$name;
}
}

if ($_GET['audio'] == "0") {$trueaudio = 0; setcookie('audio','0',time()+2592000,'/');}
else if ($_GET['audio'] == "1") {$trueaudio = 1; setcookie('audio','1',time()+2592000,'/');}
else if ($_GET['audio'] == "2") {$trueaudio = 2; setcookie('audio','2',time()+2592000,'/');}
else if ($_COOKIE['audio'] == "0") {$trueaudio = 0;}
else if ($_COOKIE['audio'] == "1") {$trueaudio = 1;}
else if ($_COOKIE['audio'] == "2") {$trueaudio = 2;}
else {$trueaudio = 0; setcookie('audio','0',time()+2592000,'/');}

$settings = new settings();

var_dump($settings->get('audio'));
//this outputs 'bool(false)'
//which is simmalar to
echo $settings->get('audio');
//which outputs nothing

//you have to define the value of that variable in the class:
$settings->set('audio',$trueaudio);

///now we can
var_dump($settings->get('audio'));
//this outputs 'string(1) "1"'
//which is simmalar to
echo '<br /> echo = '.$settings->get('audio');
echo '<br /> $trueaudio var echo = ' . $trueaudio;

phnord

6:21 pm on Dec 13, 2007 (gmt 0)

10+ Year Member



So I've been trying to break in to classes.

What version of PHP? PHP5 is drastically different than PHP4 mostly with regards to OOP. It may as well be a completely different language IMO. private, public, protected are not available in PHP4

I want to set a variable once and never have to deal with it again (by using the variable through out all of my PHP code). I've hit a few snags...mostly because the example code I've seen is anything but useful!

Why not define the constant? That is what it's essentially used for.

define( "MY_VAR_NAME", "My var value" );

JAB Creations

2:33 am on Dec 14, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



PHP5, even my live server uses it. :)

I'm not sure what constants are most useful for?

- John

RonPK

12:50 pm on Dec 14, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Constants are useful if you want to set a "variable" once and never have to deal with it again ;)

An important advantage over variables is that constants are available in all scopes. So inside a function or class you don't need to use

$GLOBALS['myvar']
or
global $myvar
. You can simply type
MYCONSTANT
to address the constant.

[edited by: RonPK at 12:51 pm (utc) on Dec. 14, 2007]

JAB Creations

6:08 pm on Dec 14, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



What is the difference between a constant and a class then? Thanks.

- John

RonPK

6:28 pm on Dec 14, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



A class is a set of related properties and methods.

class MyCart { 
var $items;

function MyCart() {
$this->items = array();
}

function addToCart($itemID) {
$this->items[] = $itemID;
}

function countItems() {
return count($this->items);
}
}

(PHP 4 code)
To use the class, call it like this:

$aCart = new MyCart();

That immediately calls the
MyCart()
-method, which makes an array of the items-property. Note the identical names of the class and the constructor method.

To add an item to the cart:

$aCart->addToCart($anItemID);

To find out how many items there are in the cart:

echo $aCart->countItems();

Of course all that can done be with 'normal' code too. Classes are just a way to get your code more organized, which usually makes it easier to reuse it elsewhere in your project or in other projects.

[edited by: RonPK at 6:36 pm (utc) on Dec. 14, 2007]

RonPK

6:35 pm on Dec 14, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



difference between a constant and a class

To keep things simple, class constants were introduced in PHP 5 ;)

class MyCart { 
private $items;
const VAT = 0.19;

[..]
}

JAB Creations

6:48 pm on Dec 14, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



So in other words a class is an advanced constant (which is more advanced then a variable) with the ability to better organize information across multiple files then a constant? I could see a counter being used as a constant where as shopping cart items would be better served by class.

- John

cameraman

6:50 pm on Dec 14, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



While I was working on this, RonPK got a good answer posted right up. This one points out another advantage to classes so I'm posting it anyway.

Short version:
A class is a collection of variables and the functions which operate on those variables.
A constant is a scalar value which does not change throughout the execution of the program.

Example:
You have a real estate site. The site has realtors and properties. You could develop a class for each of those entities. The realtor class might have variables such as name, address, telephone, email. The property class might have variables such as address, room qty, price, and a picture.

You could define a function called 'display' for each. The display function for the realtor class would echo his/her contact information. The display function for the property class would echo its features and its photo. It's a way of thinking that keeps things tidy, is easy to reuse wherever you need it, and functions don't "bump" into each other - in this case you get to reuse the descriptive "display" function name without complicating it as in "realtor_display" and "property_display". In addition, since programmatically there's no difference between one realtor and the next or one property and the next, you can reuse instances of the classes for lists of realtors or properties. If you're only selling single-family-residences now, but in 6 months you decide you want to sell condos, it's easy enough to add a little to the property class without messing up your previous work.

Let's say that the realtors' commission rate is the same for all at any given time but it goes up and down with the market strength. If you have several scripts which need to use that rate for display or calculation, you could define that value as a constant in a file to include in those other scripts. The advantage is that when it changes you only have to modify it in one location, and, as RonPK said, it has global scope (which I didn't know).

JAB Creations

7:21 pm on Dec 14, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I've been working on replacing my current procedural programming with the classes (not sure if my last posted code necessarily counts as OOP) and have it set as a header includes that I am using in conjunction with one other file before I begin merging it to the rest of my site. So as an includes I am trying to call the following function...

class settings {
public function hello() {echo 'hello';}
}

So on the file that includes this code via the includes I haven't had much luck? I am not even sure I've personally written any functions in PHP though I've had more then my share of writing them in JavaScript.

I tried the following for example...

include("classes.php");
$setting->hello();

How far off am I?

I am starting to get a sense of how a class function might be useful. Thanks!

- John

cameraman

7:28 pm on Dec 14, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



After you've defined the class, you have to create an instance (object) of it to use it, like RonPK did. With yours, you would do:
include("classes.php");
$setting = new settings();
$setting->hello();

JAB Creations

7:51 pm on Dec 14, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Oh I did have it...I just was trying the non-plural version of the plural version. ;)

In that case there is a nifty PHP script that I've been using for I recall off the bat for at least two different reasons. I'll use my referrer version of the script. However I can vaguely foresee using this script as a class function and then somehow dynamically generating my results.

I get some undesirable traffic though I have changed the words to be more appropriate for posting purposes. The script will detect types of "h20" in the referrer (from search engines effectively). If something matches I'll redirect the visitor elsewhere. I also use this as a useragent blacklist (if an undesired agent matches then PHP = die(). So I'm not sure how to approach forming this in to a function, then making sure the variables will match for both types of usage for the then function? Disclaimer: I didn't nor still couldn't write this code from scratch but I can't think of anything else I would desire to turn in to a function at the moment that would actually be useful!

- John

<?php
$referer = $_SERVER['HTTP_REFERER'];

$searchstrings = array
(
'h20' => array // $searchstrings['h20']
(
'water',
'ice',
'snow',
)
);

if ($referer == '') {
$result = FALSE;
}else{
$result = FALSE;
//by switching to a multi-dimensional array, we just need to iterate over the sub-arrays now. ie: another foreach loop.
foreach ($searchstrings as $group) {
foreach ($group as $ua){
if (stristr($referer,$ua)) {
$result = TRUE;
//because this is a nested foreach loop, we need the break to leave BOTH loops, therefore the optional int at the end of the tag
break 2;
}
}
}
}

// Redirect h20
if ($result == true) {header("Location: http://www.example.com/redirect.php?lookingfor=h20");}
?>

gergoe

8:53 pm on Dec 14, 2007 (gmt 0)

10+ Year Member



You could do this:

<?php 
class settings {
//
// Variables (properties)

private $searchstrings = array('h20' => array ('water','ice','snow'));
//
// Functions (methods)

private function check_referer() {
$referer = isset($_SERVER['HTTP_REFERER'])?$_SERVER['HTTP_REFERER']:'';
if ($referer == '') {
return false;
} else {
foreach ($this->searchstrings as $group)
foreach ($group as $ua)
if (stristr($referer, $ua)) return true;
}
return false;
}
public function redirect_h20_to_url($url) {
if ($this->check_referer()) {
header("Location: ".$url);
exit();
}
}
}
//
// Instantiate class

$class = new settings();
//
// Call the instance method

$settings->redirect_h20_to_url('http://www.example.com/redirect.php?lookingfor=h20');
?>

This is done using the class examples as in earlier posts, but if you want to do it without classes, separating the check_referer as a function is a good idea anyway, makes easier to surround it with code, like it is done in the redirect_h20_to_url function.

JAB Creations

10:23 pm on Dec 14, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I'm looking at this and I'm already seeing the connections. There is an error...

Call to a member function redirect_h20_to_url() on a non-object

Fixed the issue! I've also made a temporary test case on my site where you just search for "water" on the local search engine. I've changed the default POST to GET previously and it's now more useful then I first imagined. Here are the changes I made (and added some filler to attain a ten word minimum for the engine to index the page). I'll be working on implementing the useragent blacklist and testing that out next! :) Thanks for all the help and advice!

- John

<?php
class settings {
//
// Variables (properties)
private $searchstrings = array('h20' => array ('water','ice','snow'));
//
// Functions (methods)
private function check_referer() {
$referer = isset($_SERVER['HTTP_REFERER'])?$_SERVER['HTTP_REFERER']:'';
if ($referer == '') {
return false;
} else {
foreach ($this->searchstrings as $group)
foreach ($group as $ua)
if (stristr($referer, $ua)) return true;
}
return false;
}

public function redirect_h20_to_url($url) {
if ($this->check_referer()) {
header("Location: ".$url);
exit();
}
}
}
//
// Instantiate class
$class = new settings();
//
// Call the instance method
//$settings->redirect_h20_to_url('http://www.example.com/redirect.php?lookingfor=h20');

//$class = new settings();
$class->redirect_h20_to_url('http://www.example.com/redirect.php?lookingfor=h20');

?>
<title>water</title>
<h1>water</h1>
<p>This is a test page for the word water and I hope this test is successful!
Be sure to explore Earth metal sound water sound with water.</p>

JAB Creations

11:02 pm on Dec 14, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Ok so here is my attempt to merge the user agent black list in to the current script. User agents that are found (bad, evil, and potroast) should be redirected. I'm using Chris Pederick's User Agent Switcher in Firefox to test this.

I'm not seeing the script trigger however? Here is what I have, what am I overlooking?

- John

<?php
$useragent = $_SERVER['HTTP_USER_AGENT'];

class settings {
//
// Variables (properties)
private $searchstrings = array('h20' => array ('water','ice','snow'));
private $useragents = array('badua' => array ('bad','evil','potroast'));

//
// Functions (methods)
private function check_requested() {
$referer = isset($_SERVER['HTTP_REFERER'])?$_SERVER['HTTP_REFERER']:'';
if ($referer == '' ¦¦ $useragent == '') {
return false; $result = false;
} else {
foreach ($this->searchstrings as $group)
foreach ($group as $ua)
if (stristr($referer, $ua) ¦¦ stristr($useragent, $ua)) return true; $result = true;
}
return false; $result = false;
}

public function redirect_h20_to_url($url1) {if ($this->check_requested()) {header("Location: ".$url1); exit();}}
public function redirect_badua_to_url($url2) {if ($this->check_requested() == true) {header("Location: ".$url2); exit();}}
}
//
// Instantiate class
$class = new settings();
//
// Call the instance method
//$settings->redirect_h20_to_url('http://www.example.com/redirect.php?lookingfor=h20');

//$class = new settings();
$class->redirect_h20_to_url('http://www.example.com/redirect.php?lookingfor=h20');
$class->redirect_badua_to_url('http://www.example.com/redirect.php?403=badua');

?>
<title>water</title>
<h1>water</h1>
<p>This is a test page for the word water and I hope this test is successful!
Be sure to explore Earth metal sound water sound with water.</p>

[edited by: JAB_Creations at 11:04 pm (utc) on Dec. 14, 2007]

JAB Creations

11:10 pm on Dec 14, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



WOOHOO! This officially owns! Using the useragent "potroast" to test this out. I still have this up for now on my website if you do a search for it (if it's like a week later then I probably took it down)...but here is the script none-the-less! So it handles both the referrers and bad useragents!

- John

<?php
$useragent = $_SERVER['HTTP_USER_AGENT'];

class settings {
//
// Variables (properties)
private $searchstrings = array('h20' => array ('water','ice','snow'));
private $useragents = array('badua' => array ('bad','evil','potroast'));

//
// Functions (methods)
private function check_requested() {
$referer = isset($_SERVER['HTTP_REFERER'])?$_SERVER['HTTP_REFERER']:'';
if ($referer == '' ¦¦ $useragent == '') {
return false; $result = false;
} else {
foreach ($this->searchstrings as $group)
foreach ($group as $ua)
if (stristr($referer, $ua)) return true; $resultreferer = true;
if (stristr($useragent, $ua)) return true; $resultua = true;
}
return false; $result = false;
}

public function redirect_h20_to_url($url1) {if ($resultreferer = true) {header("Location: ".$url1); exit();}}
public function redirect_badua_to_url($url2) {if ($resultua = true) {header("Location: ".$url2); exit();}}
}
//
// Instantiate class
$class = new settings();
//
// Call the instance method
//$settings->redirect_h20_to_url('http://www.example.com/redirect.php?lookingfor=h20');

//$class = new settings();
$class->redirect_h20_to_url('http://www.example.com/redirect.php?lookingfor=h20');
$class->redirect_badua_to_url('http://www.example.com/redirect.php?403=badua');

?>
<title>water</title>
<h1>water</h1>
<p>This is a test page for the word water and I hope this test is successful!
Be sure to explore Earth metal sound water sound with water.</p>