I'm writing a power plugin for wordpress that basically supplies a bunch of functions to make development easier.
Don't worry about the wp stuff though, this is a PHP question. I have one master class 'my_wp_funcs', and a few other large classes that do different things, which I've written separately and work on their own, for example: insert a new post.
I would like to be able to use this syntax:
$wpfuncs = new funcs;
$wpfuncs->createpost($args);
$wpfuncs->addimage();
where createpost class extends funcs class, along with other classes that extend funcs too.
I've been reading up on abstraction, but am getting continual errors. Here's a trimmer version of what I have:
<?php
$wpfuncs = new funcs;
$wpfuncs->createpost($args);
abstract class funcs
{
abstract protected function createpost();
public function createpost($args){
$tool = new $this->boss_posttype('derp', 'derps');
}
}
class createpost extends funcs{
public function __construct(){
//do stuff
}
}
Cheers for any help!
You can't define the method as abstract in the abstract class and then define it for real in the same class. You also can't call the abstract class directly.
You probably want something like this:
abstract class funcs
{
abstract public function createpost($args);
}
class myFuncs {
public function createpost($args){
$tool = new $this->boss_posttype('derp', 'derps');
// do other stuff
}
}
$wpfuncs = new myFuncs();
$wpfuncs->createpost($args);
Note that your implementation goes in your own class, and that implementation has to match your abstract definition. (they both have to be public and they have to accept the same arguments)
Related
I currently have an abstract class which i am extending to other controllers. I have a abstract function within the abstract class which takes the value and places it in the __construct.
abstract class Controller extends BaseController {
abstract public function something();
public function __construct(Request $request) {
if (!is_null($this->something())){
$this->global_constructor_usse = $this->something();
}
}
}
My problem is that, on controllers that don't require this abstract function, I am having to place in the empty function.
class ControllerExample extends Controller {
public function something(){
return 'somethinghere';
}
}
Is there anyway to making the abstract function optional, or have a default value?
class EmptyControllerExample extends Controller {
public function something(){}
}
It is not possible to have a abstract method optional, as it is implied in PHP that all abstract methods must have an implementation.
There are legit use cases for optional abstract methods, yes: event handlers, metadata describers, etc. Unfortunately, you'll need to use regular, non-abstract methods with an empty body, and indicate in PHPDoc that they will do nothing unless extended.
Be wary, though: this can very quickly turn into code smell by diffusing a class responsability with their children. If you're dealing with generic events, you can look into Laravel's own event system, or the Observer pattern instead.
Abstract functions in a parent class, should only be used if its required by your application to implement the following method in all controllers who inherits from it, clearly it is not the case.
In this case i would make a trait. Here you create a trait which can be implemented by the classes who needs it. Notice the use keyword usage, use somethingTrait;
trait SomethingTrait
{
public function something()
{
echo "something called";
}
}
class Controller
{
use SomethingTrait;
public function run()
{
$this->something();
}
}
phpfiddle link
Another aproach could be doing a class inheritance structure, if the controllers you want to implement the methods has something in common. Where you would implement your special method in CrmController, where you still would be able to create shared methods in the abstract controller.
AbstractController
|
CrmController
|
CompanyController
For your question, 'Is there anyway to making the abstract function optional or have a default value?' No, and you are down the wrong path if you are trying to make abstract function optional. Hope my suggestions can help.
I have a below program
<?php
abstract class foo
{
abstract public function callme();
public function testing()
{
return $this->callme();
}
}
class bar extends foo
{
public function callme()
{
return "hello";
}
}
$objBar = new bar();
echo $objBar->testing();
?>
I defined abstract class foo. Is it compulsory to write abstract before class ? Because if i removed abstract i am getting fatal error.
Yes, if it contains abstract methods.
By declaring a method as abstract you are saying that in order to use this class, extending classes must implement the abstract method.
Your foo class cannot be instantiated unless callme is implemented, hence it must be declared abstract.
These concepts are perhaps better explained with a real world example than your standard abstract class Vehicle, class Car extends Vehicle tutorials.
Let's say we have a reporting system that does some querying on the database.
We find that all reports must be implemented in a standard way to share code and help with future maintenance.
So we define:
abstract class Report
{
}
For the sake of argument, all of our reports require a database connection.
abstract class Report
{
/** #var PDO */
protected $dbh;
public function __construct (PDO $dbh)
{
$this->dbh = $dbh;
}
/**
* #return array
*/
abstract public function getData();
}
Here we have also decided that all of our reports must implement a public getData method that returns an array.
This means:
We can ensure all our reports have a database connection
We can instantiate and then run each report in the same way
The abstract class definition has enforced the way we consume this code and makes sure that every type of report, regardless of which developer on your team wrote it, conforms to the convention we have decided.
Other code is then able to select a report from user input, run it, and do something with the result of getData (such as writing it to a CSV file) knowing that it will be an array.
I'm working on a MVC application in which the Model is implemented using an abstract base class that all actual models have to extend. In every model there is some info about that model, currently implemented as an array, let call that protected static $info. So, every model has a different $info array. Now, the base class has lots of functions that use data from that array, and at the moment every one of those functions starts with something like the example save() function below.
abstract class BaseModel {
function save(){
$className = get_called_class();
$modelInfo = $className::$info;
/* lots of other stuff */
}
}
class User extends BaseModel {
protected static $info = array("tableName" => "tblUsers", etc...)
}
In my understanding, this can be resolved by making the BaseModel a trait instead of a constructor, since when traits define static properties, each inheriting class does have their own values. I would copy the $info array from the implementation of the Model to the trait, probably in the constructor, so that I can use self::info['tableName'] in all the functions in the BaseModel...
Would this be a good idea?
The simplest and most appropriate tool for the job would be to use late static binding:
function save(){
$modelInfo = static::$info;
/* lots of other stuff */
}
I was just wondering if the next situation could be possible or not, I've read the PHP Manual documentation, but I would like another perspective because it's not so clear for me.
So I have for example one class:
class SomeClass {
public function someFunction() {
...
}
}
And an extension of it:
class Extension extends SomeClass {
public function someOtherFunction() {
...
}
}
My question is, could I be able to use the public functions inside the classes on both ways, the main class's function inside the extended function and the other way around?
And would I be doing that how?
You can use both functions from class Extension, but only someFunction() from class SomeClass.
Extension does not change the original class, it just incorporates it into a new one.
You can use the public and protectedfunctions of your parent in the extended (child) class:
class Extension extends SomeClass
{
public function someOtherFunction() {
$foo = $this->someFunction(); // from parent class
return $foo;
}
}
When class "Extension" is created, its basically a copy of "SomeClass" which you can modify in the way as you can add new functions or overwrite those of the parent class.
The parent does not know about the Extension (it can be extended multiple times, eg "JSONRequest extends Request", "XMLRequest extends Request"). Calling extended functions from within the parent makes no sense, since the parent class can never know which childs function it should call in such a situation. This type of Inheritance is one of the basic concepts of OOP and clear interfaces.
In other words, no it will never work the other way round. And it should not.
Basically I'm looking for feedback or guidance on something I've created this week at work. The problem was that I had two types of document upload. These types both shared methods like upload, isUploaded, move etc. But, in some instances they both had unique functionality.
So I thought the best approach to handle this would be to create an abstract class which contains the common functionality and 2 separate classes which extend the base abstract class in order to inherit the common functionality.
So I have:
abstract class Upload {
protected $_id;
protected $_name;
protected $_dbTable;
abstract public function create(Filter $filter) {}
abstract public function update(Filter $filter) {}
public function __construct($id){
if(!is_null($id)){
$class = new get_called_class();
return new $class($id);
}
}
protected function upload(){
//Code implemented
}
protected function isUploaded(){
//Code implemented
}
protected function move(){
//Code implemented
}
}
Class Book_Upload extends Upload {
$dbTable = 'book';
public function __construct($id){
//Database stuff to obtain record information
//Set protected member variables
$results = $databaseCall();
$this->_id = $results['id'];
$this->_name = $results['name'];
}
public function create(Filter $filter) {
//Code implemented
}
public function update(Filter $filter) {
//Code implemenetd
}
//Other unique functions
}
Class Magazine_Upload extends Upload {
$dbTable = 'magazine';
Same as Booking_Upload but with additional functionality
plus abstract methods
}
My query is, am I using abstract methods correctly? Have I followed the correct path. Also, I'm not sure I need the construct in the abstract class. What if someone attempts to call $upload = new Upload($id)?
Any class should provide a single type of functionality (Single Responsibility Principle, example: Single Responsibility Principle - A hard to see example?).
An upload class must only deal with uploads. Without more code, I smell an over-functional class from your words that tries to accomplish both the upload and document-spesific tasks.
So before going that way, you should define well what these classes will be doing. Are those document-spesific functionalities really related to the actual act of uploading?
You're extending class doesn't call parent::__construct() so the abstract __construct won't make any difference.
You are using abstract classes correctly; they are base classes that are to be built upon by other classes that share common functions and/or will have the same functionality but is implemented differently.
Abstract classes are a base to be built upon that provide common functionality and structure to other classes.