split extended classes over different files (php) - php

Szenario
I got a class as extend of an abstract class. The abstract class loads my files & extensions with their methods (link to pastebin for abstract class).
This gets called in my extends class like this (shortened & simplified - typos are only here at the Q-code):
class Pagination extends Pagination_Base
{
function __construct()
{
// loads the file "first.class.php" in the abstract class
parent::load_file( 'first' );
// stores the class as object in the abstract class, so we can access the methods and properties
parent::load_extension( new oxoFirst() );
}
}
Problem/Question
Now i got the error "Cannot redeclare class {$classname}".
I want to use my abstract class but still be able to move classes that contain extensions into separate files. Is there any way to do this?
Thanks in advance!

Use include_once instead of include in the load_file function.

Related

How to generate a .class.php file on the software Dia with the plugin uml2php5 with an abstract class?

I need to generate a .class.php from an UML chart with uml2php5 on Dia.
There is no problem with the instanciable class which have attributes and methods, the file is correctly exported.
The issue is with the abstract class. There is no file created according to the abstract class.
You can find the generated code below :
<?php
require_once('User.class.php');
class Yesmeet extends User {
public final function BecameNomeet() {
}
}
?>
Could you help me to generate the abstract class User.class.php ?
Thank you
Actually, the issue was that my abstract class hadn't attributes neither methods.
So umltophp can't create a class without attributes and methods.
I have the answer to my question but a general question appears to me :
In the object language, can we create an abstract class without attributes and methods ?
Thanks

PHP custom autoload function using spl_autoload_register won't trigger for inherited classes

Not sure what i'm doing wrong here, hoping someone can help.
I built the following class with the purpose of detecting when a requested class has not been included so it can be included. I also wanted it to include any inherited classes not included.
The registered onAutoload function triggers as expected when calling a class not already included.
However if calling a class that inherits another class that hasn't been included, the registered onAutoload function does not trigger which is primarily what I want this to do.
I tested this using the default __autoload($class) and it triggers for inherited classes as required.
Any help would be appreciated. Have included a simplified example of what i'm trying to do below and the problem I am encountering.
In Autoload.php file
class Autoload
{
private $fullPath;
function __construct ($fullPath)
{
$this->fullPath=$fullPath;
}
public function onAutoload ($class)
{
include ($this->fullpath . $class . ".php");
}
}
Autoload class created and registered as required
$thisAutoload=new Autoload ("/path/to/file/to/include");
spl_autoload_register(array($thisAutoload,"onAutoload"));
Now in the following example, onAutoload is triggered as expected.
$newClassToInclude=new ClassToInclude();
However in the following example. Assuming ChildClass in included but BaseClass is not included, onAutoload does not trigger.
BaseClass.php
abstract class BaseClass
{
function __construct()
{
print ("Base Class");
}
}
ChildClass.php
class ChildClass extends BaseClass
{
function __construct()
{
parent::__construct();
print ("Child Class");
}
}
I tested this using __autoload() function instead of my custom class and it triggered as expected.
Thanking everyone in advanced
Ok, So while not actually a fix, its an explanation and a workaround.
The example I provided wasn't 100% accurate, there's actually three classes. A base class, a second abstract class that inherits the base class, then finally the child class.
The base class was already included beforehand separate from the Autoload functionality, but the second abstract class needed to be included by the Autoload functionality which wasn't triggering.
When I disabled the logic that included the base class the Autoload functionality triggered and included the base class and the second abstract class.
So going forward, I just need to make sure there isn't separate logic including files, and just let the Autoloader do its job.

PHP Namespaces - Extend a class without extending an extended class

We are looking to build a system with core classes and the ability to extend these core classes and are looking in to using namespaces.
The problem we are having is working out if we can extend an extended class without extending the class that it extends from
For example, if we have folders and files as below
shared/classes/Entity.php
shared/classes/DatabaseEntity.php - Extends Entity.php
shared/classes/User.php - Extends DatabaseEntity.php
classes/ - Holds classes which extend from the shared classes
If we wanted to create a custom DatabaseEntity class without creating a custom User class , is this possible?
The way I understand this is that the User class will be looking in the shared namespace to extend the DatabaseEntity class but as we have extended the DatabaseEntity class, it needs to look at the top level classes directory
Example of shared/classes/User.php
namespace shared;
class User extends DatabaseEntity {
}
Example of shared/classes/DatabaseEntity.php
namespace shared;
abstract class DatabaseEntity extends Entity {
}
Example of classes/DatabaseEntity.php
namespace custom;
use shared\classes\Entity;
abstract class DatabaseEntity extends Entity {
//Some custom functionality to extend shared/DatabaseEntity
}
So if we didn't want to change the User class to say
use custom/DatabaseEntity
Then is this possible?
Hopefully that makes sense
Thanks in advance for any help
If you don't want to add to User class
use custom/DatabaseEntity
and you want to extend custom/DatabaseEntity
you may just change class declaration from
namespace shared;
class User extends DatabaseEntity {
}
to
namespace shared;
class User extends \custom\DatabaseEntity {
}
if you want to extend \custom\DatabaseEntity.
If it's not want you want to achieve I cannot understand your problem - you ask two questions.
You asked
If we wanted to create a custom DatabaseEntity class without creating
a custom User class , is this possible?
The answer is - yes, you just created it in your example. You created custom DatabaseEntity class without creating custom User class.
But if you want to achieve:
it needs to look at the top level classes directory
you need to tell User class to extend specific class - so you will need to extend using fully qualified class or import namespace using use and creating alias
I don't know if I understand you well, but you want to create CustomDatabaseEntity class that will extend DatabaseEntity and you don't want that CustomDatabaseEntity extends User class.
It's of course possible. You can create as many child classes as you want. As User class is defined that it extend DatabaseEntity class it will even don't know that you created CustomDatabaseEntity
I also think that you are using it a bit wrong. If DatabaseEntity have anything common with database and not with User itself, you should rather create Interface DatabaseEntityInterface, those two DatabaseEntity classes should implement interface
and then in User class you should pass it as constructor argument
class User {
protected $dbi;
public function _construct(DatabaseEntityInterface $dbi) {
$this->dbi = $dbi
}
}
and later you can pass to User class either class for shared folder or the one from classes

Force child classes to override a particular function in PHP

I am creating a reporting library in PHP and developed an abstract class named ReportView. This will provide the basic functionality of a report like Generating header and footer, create parameter form.
There will be another function named generate_report in this class. Currently it is empty in abstract class as at this level we do not know the contents of report. Further it includes a render function which calls this generate_report function and sends output to browser.
So I need whenever a child class inherits from ReportView it must implement
the generate_report method otherwise PHP must give error. Is there any keyword or method through which we can enforce implemetation of a specific function.
Do the following:
abstract class ReportView {
abstract protected function generate_report();
// snip ...
}
class Report extends ReportView {
protected function generate_report() { /* snip */ }
}
Any class that extends ReportView and is not abstract must implement generate_report (and any other abstract function in its super classes for that matter).
Sounds like you’d be better off creating an interface, which would enforce you to define those methods in classes that then implement this interface.
<?php
interface ReportInterface {
public function generate();
}
class MyReportClass implements ReportInterface {
}
Instantiating MyReportClass here will throw a fatal error, telling you generate() has not been implemented.
Edit: You can also create abstract classes that implement this interface. You can have your abstract class contain any methods all extending classes need, and have your interface define any methods you need to be defined by extending classes.
You need to declare the method as abstract as well (and don't give it a method body), otherwise the derived classes will not be forced to implement it.
Alternatively, you could implement the method but have it just throw an Exception (not sure why you would want to do this).
Lastly, if all the methods in your base class are "abstract" (do not have bodies) then you can make the class into an Interface instead.

Inheritance in CodeIgniter

I am building a series of forms, and I am trying to inherit the functionality of a parent Form class into all the forms. For example,
LeaveForm extends Form (Model)
LeaveFormController extends FormController
I am handling all the leave form specific stuff in LeaveFormController and LeaveForm.
In LeaveFormController constructor, I simply call the parent class constructor, then load the LeaveForm Model. And in FormController constructor, I load Form model.
My problem is, I get an error,
Cannot redeclare class form in Form.php
Have I got my architecture wrong? How do I handle this ?
check if the class has already been initialized like this:
if (!class_exists('classname'))
{
// ok fine create new instance now
}
Possibly when you $this->load->model('Form'), you manually included the models/form.php file?
In your leaveform.php model file, make sure you load the superclass model you extend using codeigniter's model loading mechanism instead of require or include. Codeigniter has a loader that keeps track of already-loaded files to avoid redeclaring classes, but you need to use $this->load to use it. It won't know about files loaded directly with include or require.
So at the top of leaveform.php, use this:
$CI =& get_instance(); $CI->load->model('Form');
This is not related, but you will have pain unless you namespace your CodeIgniter model classes the same way you namespace Controller classes.
Try using FormModel extends CI_Model {}; Instead of Form extends CI_Model {};

Categories