Ok, so I am building a web application relying on Zend PHP....
Before having to read everything to describe my nested functions, what I need is to be able to call a function from one class to another, which neither are extended upon another, are already extending a db constructor, which are all independently separate files called by one master initializing script .... (?) ... Thanks in advance, and there is a better example below as to what I mean.
My HTML Page calls a "master" include list which initializes and creates all the instances of all my classes so that all pages have common access to the functions. i.e. require('app_init.php');
Here is the most important excerpt of app_init.php:
require_once('class-general.php');
require_once('class-users.php');
require_once('class-identities.php');
$general = new General();
$users = new Users($db);
$iden = new Iden($db);
---class-general.php
$general is my basis for stupid common functions I use, as well as the DB constructor that all classes can be extended from.
----class-users.php
<?php
class Users extends General{
public function getUserID(){....random block of auth code.... return $randomID#; }
}?>
-----class-identities.php
<?php
class Iden extends General{
public function do_random_change_to_db($with_me){
....random prepared function using $with_me....
$this->logger->log("Someone with UserID: ". /*((?$this?) HERE:)*/ FIXME->getUserID() . " did something : ".$with_me ."." , Zend_Log::INFO);
$success="gucci";
return $success;
}
}?>
Right now, I am being tossed a PHP error for
Fatal error: Call to undefined method Iden::getUserID() in ...`
What would be the best way to go about this? I've tried to include one class file with the other one, but i dont exactly want to create a $FIXME= new Users(); either to save on memory space.
I also honestly would prefer to not extend any more classes off another at this time.
Thank you in advance.
If the getUserID method does not depend on any instance state (and it doesn't look like it does, though you haven't made it entirely clear), making it static will allow you to call it like so:
Users::getUserID();
If it does depend on instance state, you will need to call it on an instance of the Users class.
It seems to me that General's methods should actually be static as well, or perhaps even be free functions outside of a class. Remember: classes are used to encapsulate state. If there's no state that needs to be encapsulated, use class (static) methods or simple functions. Do not needlessly complicate your code by introducing objects and inheritance in which those paradigms don't make sense.
Related
As I looked for the new PHP7-features I stumbled upon anonymous classes.
I didn't understand when they should become useful, and looked for an example.
I read this article, but I don't see the benefits of this feature.
In the last section before the conclusion they wrote the following about the advantages:
One advantage is that we no longer need the named extension. Normally the named extension would be hidden away in some included file, if you ever needed to see how it is defined you have to start searching for it. With anonymous classes the definition is in the same place the object is created.
On the other hand, I see a big disadvantage because you can use this anonymous class only at the place it is defined.
Can someone please explain when this feature is useful?
Especially if it can help when building custom systems or extending a CMS like WordPress (preferably in German, although English is also welcome).
Anonymous classes could be useful in writing implementation classes for listener interfaces, so you don't need to create a file or a generic class just to implement once.
One of the most elegant things about anonymous classes is that they
allow you to define a one-shot class exactly where it is needed. In
addition, anonymous classes have a succinct syntax that reduces
clutter in your code. Java in a nutshell
So, you can have an anonymous implementation of an interface or even extend a class, with additional properties or overwritten methods.
Example:
return new class(10) extends SomeClass implements SomeInterface {
private $num;
public function __construct($num)
{
$this->num = $num;
}
};
Another situation:
Provide a simple implementation of an adapter class. An adapter class is one that defines code that is invoked by some other object. Take, for example, the list() method on a class called File. This method lists the files in a directory. Before it returns the list, though, it passes the name of each file to a FilenameFilter object you must supply. This FilenameFilter object accepts or rejects each file. When you implement the FilenameFilter interface, you are defining an adapter class for use with the $file->list() method. Since the body of such a class is typically quite short, it is easy to define an adapter class as an anonymous class.
$file = new File("/src");
// Now call the list() method with a single FilenameFilter argument
// Define and instantiate an anonymous implementation of FilenameFilter
// as part of the method invocation expression.
$filelist = $file->list(new class extends FilenameFilterClass {
public function accept(File $f, string $otherInfo) {
return pathinfo($f, PATHINFO_EXTENSION) === ".php";
}
});
Some nice basic understanding and use about anonymous classes could be found on Java (I know its not PHP, but it helps on understanding) examples at https://www.geeksforgeeks.org/anonymous-inner-class-java/
I should use a anonymous class only if this class is not used anywhere else and if these class isn't changed since the first coding.
So for example a database class could maybe a candidate for using a anonymous class because it should be use only once and could be included in any other php file. In most cases the data for accessing the database is in the config file. Therefore this file should be loaded for every php file that is using the database when you want to avoid the hard coding of the database params (which is a bad idea). If you coded these class as an anonymous class in the config file you have eliminated one include whithout losing the maintainance.
I need static class (object) to store a global variable value. I'm new in PHP but i have experience in other language that have OOP concept like in Java. In Java i can make static variable and can call anywhere i want. But how to do same in PHP?
I use CodeIgniter framework , before i try this i try using session to store but i want to use another way like above. can anyone help me?
Can i do like this ?
static class myClass{
public static myVar = "";
}
Because you mentioned framework Codeigniter and use of session I assume that you need to use this in multiple controller and views.
So I there is also another way which works bit different than property of class but more similar than session (except changed value won't affect on another page).
So Use Constant.
Define it in
application > config > constant.php
page. There are many constant defined in that page, using exact same syntax you can define your values and you can use it very easily to any where.
just like if you define SITE_NAME constant in constant.php as
defined('SITE_NAME') OR define('SITE_NAME', "My Example Site");
After that you can use it anywhere in any controller, view or model of your Codeigniter, What you need to do is just echo it
<?php echo SITE_NAME; //only SITE_NAME not $SITE_NAME ?>
I hope it is what you want, if not sorry for my misunderstanding.
You can have a static-like class in PHP. But you don't have an app-cycle in PHP. This means you won't get a real static (or singleton) in your whole application.
If you shouldn't be able to instantiate a class then it should be abstract and define its methods as static. However, somebody could just subclass the class and make it non-abstract. If you don't want that to be a possibility either then the class should be abstract final.
If you do this, you can call methods directly on the class in question with ClassName::methodName() syntax. Do bear in mind that classes written like this can't make use of $this because it is only valid for an object instance. If you need the class to maintain state then you will have to define a static variable and use it with self:: or static:: syntax.
abstract final class SomeClass
{
private static $var = "";
public static function setVar($newVal)
{
self::$var = (string) $newVal;
}
public static function getVar()
{
return self::$var;
}
}
A word of caution on doing this though, use of abstract classes/methods can very easily lead to tightly coupled code which is bad for a number of reasons.
For example, if you write a class that calls the methods of an abstract class directly by any means other than inheriting from the abstract class, then it will be impossible to unit test that class in isolation. It will always require your abstract class to be part of the test suite too, which means it's more difficult to determine whether a test failure has been caused by a fault in the class under test or in the abstract class it's depending on.
What's more, if the abstract class you're depending on serves as an accessor for a data source, then you also will not be able to mock the class during tests. Mocking is a very powerful way of verifying the correctness of a class without having to rely on the environment that the class is running in. for example, you can mock a database access class with a compatible object that always returns the same data from an array instead of hitting an actual database. This means that you can guarantee that when you run a test it will run with data in a state that you have full control over. If you access a database via an abstract class's methods then you can't replace that for testing and suddenly you may end up with a test suite that might succeed or fail depending on the state of the database at the time you run the test. Even worse, if your tests involve writing to the database then you could potentially corrupt your data source when running tests.
I'm trying to grasp the Open/Closed principle (in my case for PHP, but that shouln't really make a difference).
The way i understand it is that a class is never open for modification. Only for bug fixing. If i wanted to add new code to the class, then i'd have to create a new one and extend the 'old' class. That's the only way i can add new code to it.
In a way i can see the advantages of this. Because basically you create some sort of versioning system, where old code always work, but you can always try to use the new classes too.
But how does this work in practice? I mean, suppose i have the following class:
class MyObject
{
public function doSomething()
{
echo 'Im doing something';
}
}
So somewhere i'm probably instantiating this class:
$obj = new MyObject();
But then i decide that it's good to have another method in that object. So i can do something else too. According to the OCP i can't modify the class. So i have to create a new one, which extends to old one right?
First problem. How do i call the new class? Because it isn't really a complete new object. Like. a User object is a User object. I can't suddenly give it completely diffent name just because it needs another method. Anyway, i create the new class:
class MyNewObject extends MyObject
{
public function doSomethingElse()
{
echo 'Im doing something else now';
}
}
Now this also means i have to change the line of code where i instantiated the "MyObject" class and replace it with the "MyNewObject" class, right..? And if that's done in more than one place, then i have to search through my source code... (Think about a method in a controller class, which almost always uses the 'new' keyword to instantiate certain classes).
The same basically applies to inheritance. I'd have to find each class the inherits the old class and have to replace that with the new class.
So basically my questions are:
How do you name the new classes which have the new methods? Just becasue i added some new functionality, doesn't mean i can give the class a whole new name...
And what if the 'old' classs is instantiated (or inherited) from multiple places. Then i'd have to find all of those places... Where's the gain?
The Open Closed Principle isn't intended to be used as a kind of version control system. If you really need to make changes to the class, then go ahead and make those changes. You don't need to create new classes and change all the places that instantiated the old one.
The point of the Open Closed Principle is that a well-designed system shouldn't require you to change existing functionality in order to add new functionality. If you are adding a new class to the system, you shouldn't need to search through all your code to find the places where you need to reference that class or have special cases for it.
If the design of your class isn't flexible enough to handle some new piece of functionality, then by all means change the code in your class. But when you change the code, make it flexible so you can handle similar changes in the future without code changes. It's meant to be a design policy not a set of handcuffs to prevent you from making changes. With good design decisions, over time your existing code will require fewer and fewer changes when you add new functionality to the system. It's an iterative process.
I would argue that by adding a function, you're not modifying the class behavior.
In all the instances where doSomething() is currently being called in your app, simply by adding doSomethingElse() to the class will have no effect. Since you're not changing doSomething(), the behavior is the same as it was before.
Once you determine that your doSomething() implementation isn't cutting it for certain circumstances, you can extend the class and override doSometing(). Again, the original still behaves the same as it always did, but now you have a new doSomething() to work with also.
I realize that this goes against the strict definition of open/closed, but this is the real world, and that's how I interpreted that principle in my code.
You need to create a constructor in your MyNewObject class which calls the parent class' constructor:
function __construct() {
parent::__construct();
}
This way you can instantiate the new class and still access all the functionality of the extended one.
You can then also override any function in the parent class (as long as it is not marked final of course).
So you could do:
$newObj = new MyNewObject();
$newObj->doSomething();
$newObj->doSomethingElse();
I was wondering if there is any major different in the following, and whether one is more 'standard' than the other:
<?php
class Account extends Database {
public function myMethod()
{
// Do something
}
}
?>
or
<?php
require('database.class.php');
class Account {
public function myMethod()
{
// Do something
}
}
?>
Cheers :)
Edit:
This question actually relates to a tutorial series I have been following which describes the above two methods - which didn't make any clear sense.
So thank you for the constructive answers on clearing that one up!
Those are two completely separate language constructs.
Your first example deals with inheritance. Basically, you already have a class called Database, but you want to have a specialized version of that class to handle accounts. Rather than build a brand new Account class and copy/paste all the functionality you already have in your Database class, you simply tell PHP that you want to use the existing Database class as a baseline. You create any account-specific functionality in the new Account class, and anything database-related comes automatically. This is assuming, of course, that you have some way of specifying where the Database class is defined - for example, a require declaration at the top of the class, or an __autoload() or spl_autoload_register() function call defining a way to find and locate the file containing the Database class.
In your second example, your database-related code is completely separated from your Account class. They're completely distinct entities, and if you wanted to do anything database-related in your Account class, you would have to explicitly instantiate a new Database object within that class (or pass it to that class, or one of its functions, as a parameter.
Basically, extends helps define what a class is, whereas require shows where a class definition (or other code) is stored.
Both code snippets aren't even equivalent.
The first declares Account to extend Database, a is-a relation.
In the second code snippet, you are simply saying that you require 'database.class.php' ... and that neither has anything to do with OO, nor defines a is-relation from Account to Database.
Both are completely different in first one class is inherited by another class but in the second one the class is included in your script only.
Means if you extend all the public and protected methods are available in your derived class and you can create object of derived class and can use methods with derived class's object.
But in the second method the class is included in your script and require this class it's own method and work independently.
The first means you create a new class, which has all the functionality of Database class and those you implement.
The second means that you create a new class, but it doesn't have Database functionality since it's not extending it. If you need database access in your Account class, you can create an instance in constructor, or pass already created instance as constructor parameter.
It's hard to say what is more standard, since it depends on what You actually want to achieve.
To put it in most simple terms:-
require or include is structural programming.
extends is object oriented
I'm creating a website with structure like this:
class main { }
class mysql extends main { }
class user extends main { }
class etc extends main { }
The idea is for these classes to use functions from each other. This doesn't work. How can I call a function from mysql in user?
EDIT:
All errors are similar to this one:
Fatal error: Call to undefined method user::function_in_mysql() in C:\foo.php on line 8
Martti Laine
The idea is for these classes to use functions from each other.
That's not what you're doing: Inheritance goes only one way. mysql, user, and etc inherit mains abilities but not those of each other.
You could have mysql extend user extend etc so that at least mysql can call all the functions but that probably won't make sense, as I think they are not ancestors but siblings to each other, fulfilling a distinctly different function.
You would have to either define any shared methods in main - often the best way to go - or introduce the classes to each other so they're able to call each other's functions. You could, for example, add an instance of each needed class as parameters to the constructor:
$etc = new etc();
$mysql = new mysql($etc);
// mysql's constructor sets $this->etc
// so that it can call etc's functions using $this->etc->function()
or, more complex, using the dependency injection or singleton patterns. I asked a related question some time ago about how to deal with this in PHP and got a lot of feedback, maybe it gives you some inspiration.
Having a class extend another makes the methods of the other (parent) available to it. So user extending main only makes the methods of main available to it. If other classes extend main it doesn't allow all of them to call each others methods. You could have user extend mysql and mysql's methods would then be available to user though I don't believe that fundamentally this is what you're looking for.
I think you're looking for something along the lines of dependency injection and not class inheritance.
For example if you wanted your user class to have access to your mysql class you pass it an instance of it in it's constructor.
class user {
protected $_mysql;
public function __construct(mysql $mysql) {
$this->_mysql = $mysql;
}
public function myMethod() {
$this->_mysql->myMysqlMethod();
}
}
$mysql = new mysql();
$user = new user($mysql);
$user->myMethod();
Here's some good reading on dependency injection.
PHP Dependency Injection
Symphony Dependency Injection
The Symphony link in particular is a pretty nice read on the overview of dependency injection and how to setup a dependency container.
That's not how extending a class works. All the functions that should exist in all classes should be part of main. Then functions that are specific to mysql go in that class. I'm guessing that the classes are not as closely linked in terms of inheritance as you think. If the user class needs to make calls through your mysql class, have a variable in the user class that holds a mysql object.
To call a function from mysql inside of user you could create an mysql object inside of user and call the function.
<?php
// this is user.php
$var = new mysql(); // <--if it takes parameters in the constructor
$var->method();
...
?>
For a better answer could you provide more information, as in, what errors are you getting?