I am having a hard time finding an answer to this, I am sure it's there in front of me but I cant put it together.
//Global Variables
global $GLOBAL;
$GLOBAL['myPluginPath'] = dirname( __FILE__ );
//Main Object
class My_Class {
public function __construct() {
// Initialize Settings
require_once $GLOBAL['myPluginPath'] . '/settings.php';
$My_Settings = new My_Settings();
}
}
I want to use a variable so my code feels more organized, I feel I can read my code better when paths are defined this way and it makes it easier to change the variables so that it applys throughout the whole code if needed.
I can get the variables to work by writing this inside my methods.
public function WhatEverFunc() {
global $GLOBAL
require_once $GLOBAL['myPluginPath'] . '/settings.php';
}
The primary question here, I am wondering if this is bad practice, if not is there a better way then having to define global $GLOBAL inside each method. If however it is bad practice can you show me good practice?
There is a one other thing I am really curious about. Inside the main __construct you see I don't use global $GLOBAL because it works without it, but inside that require_once file is another class which has methods that must use global $GLOBAL inside of them. Hope someone can explain that.
Some are saying this is bad practice, I think. I read there is a singleton pattern(bad practice) and a global pattern. Not sure what I did above constitutes, I am just a little lost from what I should do here with what I am trying to achieve.
An object really should have everything needed for it to perform any function it is designed to. If not, the data should be passed via a param to it.
Part of the whole point of objects versus procedural code is that objects can be re-used over and over and in many places.
Lets use this example of why using Globals and OOP is a bad idea:
Lets say you have a great front-end bit of code, and you write it all through objects. Sometime down the track, you need to create additional reporting on the data in your site. You start to code and realize that you can re-use your classes from the front to achieve almost everything you need - but alas your code contains numerous references to globals that are only visible in the front end if called from a certain script.
That's basically just made your objects rather un-reusable.
Although it's probably not the best practise, but I often write a quick class that grabs a hold of various $GET, $_POST and other variables which might be considered "Globals" such as URL params and the like, then in my code, I either pass this information directly to the objects/functions as needed or indeed pass the entire object (rarely).
Using this approach, I am always perfectly ready to re-use objects knowing EXACTLY what they need to function as they are all required in params.
Why don't you use $GLOBALS? You don't even need to use global keyword.
The primary question here, I am wondering if this is bad practice
Well, I believe most people would say having a global state is bad practice because it is harder to manage or doing unit test. Most people would suggest you to use "dependency injection" which instead of depend on global state, you need to inject what the class need directly.
From your code it seems that you're just looking for a way to resolve your class names into file names. For that purpose it's better to use auto loaders. It takes the formality of how your classes map to file names away from the bulk of your code so that you can concentrate on actual development.
Organizing your plugins can be done by using namespaces.
Second, in most cases you don't want to instantiate classes inside the constructor because it leads to coupling, and too much coupling can stifle your project later; instead, inject the dependency:
class My_Class
{
private $settings;
public function __construct(My_Settings $settings) {
$this->settings = $settings;
}
}
To call it:
$c = new My_Class(new My_Settings());
Use this example to solve your problem
The global keyword doesn't work the way you think it does. It does not make a variable have global scope. All it does is specify to the function that you call it in that you want to use the variable in the outer scope.
For example:
$a="test";
function something() {
global $a;
echo $a; //Outputs: test
}
If you want to make a variable global so that it can be accessed from within a class, you need to use the $GLOBALS superglobal.
Related
For my latest website I’ve been trying to use classes. Mainly to teach myself more about OOP and learn through experience.
Whenever I needed a ‘variable’ within my class I created a property, for instance:
class someClass
{
var $valueToUseHere; // Only used internally - can I just use a variable?
public function doStuff()
{
$this->valueToUseHere = 60;
// Do more stuff here...
}
}
It is only now when I’ve been looking more into the code and trying to do some optimisation that I’ve noticed that my functions and classes are passing around some large objects. A lot of that bulk could be stripped away if I made all the properties that are only used inside the class into normal variables.
Are properties only used for variables that are needed outside the class and is it then acceptable to just use ‘normal’ variables within the class itself ?
Sorry if this question illustrates a lack of understanding on the subject. Unfortunately, this is where my learning is up to at this point. I’ve done some searching around “class properties vs variables” etc but not found a comprehensive answer to this.
Many thanks
It's somewhat vague what you're asking, but if valueToUseHere is not used outside of doStuff, then don't make it a property!
class someClass {
public function doStuff() {
$valueToUseHere = 60;
// Do more stuff here...
}
}
If there's no reason to share that value with other methods of the class or with the outside world, then there's no reason to clutter up your object with all sorts of properties. Not only may this cause tricky bugs with preserved state, it also forces you to be unnecessarily careful with your variable names across all object methods.
Actually class properties are variables as well. Basically you have three options:
Global variable, available everywhere, but not recommended because all parts of your code may depend on such a varialbe, changes can easily break stuff everywhere.
Class property (Note: you should define a visibility - public/protected/private) these properties are bound to the object instance and should be used for any state that the object needs to keep for further processing. Usually those might be used in more than one metohd of your class.
Variables inside a method like just
public function doStuff()
{
$valueToUseHere = 60;
// Do more stuff here...
}
The variable is just available inside the method and is thrown away at the end of the method execution.
That depends on your needs. If you are going to simply hold a value in a variable it's the best to keep it's simplicity and not define functions for setting or getting it's value. But sometimes you may need to have more controls on a variable in your class. For example you have defined an integer variable and you want it's values to be always between 10 and 1000 and also it should not be in 100,200,300,..,900. So here there is a good reason to set your variable access to private and create a public function to check what is required before setting a new value. Or in another example you may want to call another function or change another depended variable in your class exactly after this variable changed. Or if you want to make a variable read-only or write-only always you can define properties for controlling the variable value.
In brief you may prefer to use:
Properties: When you want to have control about get and set values
Variables: When you want to set or use a variable as its nature
I'm trying to improve my website engine. So I can stop setting global $vars inside functions
So now I'm setting all my global site vars with this instead:
define('ROOT_prefix', 'mysitename_');
define('ROOT_support', 'support#mysite.com');
I can access them anywhere. But it does not feel as good (or smart) practice..
I know very little about classes.. but couldn't/should't I use a class for this instead?
This works:
class ROOT {
public static $prefix = 'mysitename_';
public static $support = 'support#mysite.com';
}
And then anywhere on my site I can use this (even inside functions):
echo '<h1>Please contact support at: '.ROOT::$support.' </h1>';
Is this a good way, or is there a better way?
If the value of these "globals" will not be changed for the entire run-time of the script, then you absolutely should use constants, as this is exactly what they are for.
You should keep them all centralized in a common include file for readability.
(Edit based on comments follows)
Since it looks like you're using constants for some kind of localization of content, it might be prudent to use a class for this. As I have said: using constants for non-changing values in a procedurally oriented script isn't bad practice in itself, but in the context of localization, there are better ways.
One such would be to create a class with some static methods to translate a string based on the passed ini file, this would be in line with the dependency injection mentioned in other comments and answers here.
An example of such a class would look something like this:
class Localizer {
public static function localize($langFile, $string) {
if (!file_exists($langFile)) {
throw new Exception($langFile . 'not found!');
}
$lang = parse_ini_file($langFile);
return (!empty($lang[$string])) ? $lang[$string] : false;
}
}
You can use it like this:
echo Localizer::localize('./english.ini', 'hello') . "\n";
echo Localizer::localize('./english.ini', 'email') . "\n";
This assumes an ini file that looks like this:
; english.ini
hello = 'Hello!'
email = 'test#test.com'
Realistically, this is probably a more "proper" way than declating a boat load of constants for each language your application runs in, but it is going to open the file every time you need to localize a string, which wouldn't be optimal for a very high volume application on a large system. But, as with a constant, you will be able to access the static methods of a class in the scope of any function in your application so long as the class was included beforehand. No need to use constants or declare globals.
The most proper and efficent way to do it would be to instantiate a class instead of using static methods, which would load the files into memory once and keep them there, eliminating the need to open the file for every string translated. But this would require that you are able to pass the variable containing the instantiation of this class to every function in your code that requires it, or declare it as global, which was exactly what you were trying to avoid in the first place.
So in order to do this, you would probably need to re-structure your code to allow for dependency injection throughout.
To continue with your current code and structure, you can continue using generated constants, which will be much messier, less "proper", and not expandable, but the advantage is that you will only read the ini files once, and keep them in memory.
Or you can use a static method, which is more "proper" but needs to read a file every time you localize a string, meaning that on large systems, it could cause some inefficiency. Realistically though, if your application in low volume, you will likely never see problems arise from this.
The main advantages of this method are expandability, and clean code. While declaring constants might be more efficient in terms of file opening and memory usage in the very short term, in most cases, it's not as expandable, because you can have an unlimited number of strings and language files, which means you could end up in a situation in the future where your loading thousands and thousands of constants every time your application loads.
If you use a class, and only load the files/strings that are needed by that specific user at run time, you can avoid this, no matter how many languages and strings you support.
Static class variables aren't any better than constants. They're still globally accessible values. There's no real change.
If you want to be improving your style, you should be using dependency injection. This simply means that you pass all variables that a function or class needs into the function/class as parameters. It's that simple, really. If you want to decouple your code, you need to create borders between different pieces. That means one piece does not "reach out" and get a global variable; instead you define that piece as accepting a parameter and write another piece that passes it that parameter.
Please read How Not To Kill Your Testability Using Statics for an in-depth explanation of this topic.
You may set variable to global when you need it. Just use global ${$variablename};.
where $variablename contain name of needs variable. For example it may be array keys or values.
Declaring your properties as public allows for their modification.
If you want them to be constants, as they were when created with define, you'll have to declare them as protected and use methods to access them :
class ROOT {
protected $prefix = 'mysitename_';
protected $support = 'support#mysite.com';
public static getPrefix(){
return $this->prefix;
}
public static getSupport(){
return $this->getSupport;
}
}
This way is actually quite better than using define() actually.
It's a step forward to singleton patterns (http://en.wikipedia.org/wiki/Singleton_pattern).
Next step is the building of an Application class (ROOT name sounds fine) which would contain these constants, and perhaps load them from a configuration file.
In this Application singleton, you can build some main function, like an init() for a bootstrap, inclusion of other classes, database configuration, logging system, templating system, and so on...
I'm creating a web app in PHP5. So far, I have two "global" variables: $input and $sql. $input is the validated and sanitized input from $_GET, $_POST and $_COOKIE. $sql is an instance of my mysql(i) class.
These two are needed in almost every other class. This could be relatively easily achieved by passing them as parameters to the __construct function of each class. But that seems ... clumsy. Along with more class specific parameters and potential future global vars, it makes for unwieldy function calls.
The easy and, as I understand it, noobie alternative would be using the global keyword. I don't want to do that. I get the downsides of globals, although in my scenario (small app) they wouldn't matter much. But it's also clumsy to explicitely label them global before using them again.
A more elegant way I suppose: I have a webapp class from which I extend all other classes. This webapp class holds common functions I need in more than one other class but that do not warrant for a seperate class.
If I store $input and $sql as static variables in this webapp master class, they'd be accessible in all subclasses.
But I understand that static variables are as much frowned upon, if not more, than global variables.
Is that true?
I guess I'm one of these people who overthink everything, but I like elegant code and this looks elegant to my (amateur) eyes.
So far, I have two "global" variables
Yuck! Globals are bad. :-)
$input is the validated and sanitized input from $_GET, $_POST and $_COOKIE
Why do you make that global. Simply sanitize / normalize / whatever when you really are going to use it.
$sql is an instance of my mysql(i) class.
Again: no need to make that global. Use dependency injection.
The easy and, as I understand it, noobie alternative would be using the global keyword. I don't want to do that.
You are right: you don't want to do that.
A more elegant way I suppose: I have a webapp class from which I extend all other classes.
That also doesn't sound really correct. A class has a specific function (/ responsibility).
But I understand that static variables are as much frowned upon
Static stuff are just globals with a different name.
If you do want to make your life easier you could implement a dependency injection container.
http://php.net/manual/en/language.oop5.patterns.php
This link describes the singleton pattern which is the oo-way which provides a single global instance of a class. I'm sure this is elegant enough seeing you will otherwise being subclassing for the sake of subclassing, and not requiring them to pass as a parameter.
This is what i would do :)
Personally I would employ the singleton in this example. Singletons can be frowned upon however when used in the right situation they are perfectly fine.
I would create your "WebApp" class as a singleton, this means where ever you need those variables you simple access the "WebApp".
If you have never used a singletone before, here is an example:
class WebApp
{
private static $instance = null;
private $post_data = array();
private function WebApp(){}
public static function instance(){
if(!isset(WebApp::$instance))
WebApp::$instance = new WebApp();
return WebApp::$instance;
}
}
print_r(WebApp::instance()->post_data);
I just want to tell you that I am newbie to OOP and it is quite hard to me, but here is my code:
class functions
{
function safe_query($string)
{
$string = mysql_escape_string(htmlspecialchars($string));
return $string;
}
}
class info
{
public $text;
function infos($value)
{
echo functions::safe_query($value);
}
}
Is there any way to make this sentence : echo functions::safe_query($value); prettier? I can use extends, than I could write echo $this->safe_query($value);, but is it a best way? Thank you.
edit: and maybe I even can to not use class functions and just make separate file of functions and include that?
Yes, just define your function outside of a class definition.
function safe_query($string){
return mysql_escape_string(htmlspecialchars($string));
}
Then call it like this
safe_query($string);
Using a functional class is perfectly fine, but it may not the best way to design your application.
For instance, you might have a generic 'string' or 'data' class with static methods like this (implementation missing, obviously):
class strfunc{
public static function truncate($string, $chars);
public static function find_prefix($array);
public static function strip_prefix($string);
public static function to_slug($string); #strtolower + preg_replace
etc.
}
The point of a class like this is to provide you with a collection of generic, algorithmic solutions that you will reuse in different parts of your application. Declaring methods like these as static obviates their functional nature, and means they aren't attached to any particular set of data.
On the other hand, some behaviors, like escaping data for a query, are more specific to a particular set of data. It would probably be more appropriate to write something like this, in that case:
class db_wrapper{
public function __construct($params); #connect to db
public function escape($string);
public function query($sql);
public function get_results();
}
In this case, you can see that all of the methods are related to a database object. You might later use this object as part of another object that needs to access the database.
The essence of OOP is to keep both the data and its relevant behavior (methods) in one place, called an object. Having behavior and data in the same place makes it easier to control data by making sure that the behavior attached to the data is the only behavior allowed to change it (this is called encapsulation).
Further, having the data and behavior in one place means that you can easily pass that object (data and behavior) around to different parts of your application, increasing code reuse. This takes the form of composition and inheritance.
If you're interested in a book, The Object-Oriented Thought Process makes for a decent read. Or you can check out the free Building Skills in Object-Oriented Design from SO's S.Lott. (Tip: PHP syntax is more similar to Java than Python.)
Functions outside a class litter the global namespace, and it's an open invitation to slide back to procedural programming. Since you're moving to the OOP mindset, functions::safe_query($value); is definitely prettier (and cleaner) than a function declared outside a class. refrain from using define() too. but having a functions class that's a mix of unrelated methods isn't the best approach either.
Is there any way to make this sentence
: echo functions::safe_query($value);
prettier?
Not really. IMO having a functions class serves no purpose, simply make it a global function (if it's not part of a more logical class, such as Database) so you can do safe_query($value); instead.
and maybe I even can to not use class
functions and just make separate file
of functions and include that?
Create files for logical blocks of code, not for what type of code it is. Don't create a file for "functions", create a file for "database related code".
Starting with OOP can be a real challenge. One of the things I did was looking at how things were done in the Zend Framework. Not only read the manual (http://www.framework.zend.com/manual/en/zend.filter.input.html, but also look at the source code. It will take some effort but it pays of.
Looking at the context of your question and the code example you posted, I would advice you to look at some basic patterns, including a simple form of MVC, and the principles they are based upon.
I have recently learnt about namespaces in PHP, and was wondering, would it be bad practice to do this?
<?php
namespace String; // string helper functions
function match($string1, $string2)
{
$string1 = trim($string1);
$string2 = trim($string2);
if (strcasecmp($string1, $string2) == 0) // are equal
{
return true;
} else {
return false;
}
}
?>
Before I had this as a static method to a String class, but this always seemed wrong to me... Which is the better alternative? I have a desire to categorise my helper functions, and want to know which is the better way to do it.
Edit
So how do I then access the match function if I have declared it in a namespace? How do I stop the namespace declaration, say if I include a file beneath it which declared a new namespace, would it automatically stop references to the first? And how do I go about returning to global namespace?
I'd put it in a namespace. A class is a describes a type in php, and though you maybe operating over a type with a similar name, it's not the same type, strictly speaking. A namespace is just a way to logically group things, which is what you're using a class to do anyways. The only thing you lose is extensibility, but as you said, it's only a collection of static methods.
If they're all string-related functions, there's nothing wrong with making them static methods.
A namespace would be the better choice if you've got a bunch of global functions and/or variables which you don't want cluttering up global scope, but which wouldn't make sense in a class. (I've got a class in my own code which would be a lot better suited to a namespace).
It's good practice to stick everything in some sort of container if there's any chance your code will get reused elsewhere, so you don't scribble on other people's global vars...
As for your edit there:
Namespaces are tied to the file they're defined in, IIRC. Not sure how this affects included files from there but I'd guess they aren't inherited.
You can call the global scope by saying ::trim().
Because namespaces are so new to php, people have been doing for a long time what you did - create a class, add static methods, and use the class as if it were a namespace. It looks to me as if you are thinking about it properly.
You would use classes to categorized some sort of functions on a certain dat. Like let say you have a Student class which will hold student information and student age and student ID number;and alose there some sort of methods that return and set these data.
Moreover, you would use namespace to categorized the Classes;let say now you have another class which handle the University registration for those students and alose the other classes for managing courses. Personaly, I would put all these classes under a category (i.e. namespace) called University.
Thus, it is not even a bad practice, also it gives you more readability in your code. And that would be more underestandable for other programmers if you are working in a group.
So personally I strongly suggest you use those in your project wherever you think it is proper to use it.
Ideally, it would be best to put functions in a namespace. If you depend on autoloading though, which only works for classes, you need to put them in one or more classes.