Dynamically include all classes inheriting from MyBaseClass from a folder - php

I'm in need of some help.
I have a folder containing classes: /my/folder
I have a class file /my/otherfolder/MyBaseClass.php containing a corresponding class.
I would like to dynamically (in the sense that I do not hard code any class names inside /my/folder) load all classes in /my/folder and for the ones inheriting from MyBaseClass I would like to call the base method myBase().
I'm looking for the cleanest, easiest way. Performance is not an issue.

A very old example from code I wrote long ago... the require_once works because all the classes involved were in the same directory, which was added manually to the path.
function __autoload($class_name)
{
require_once("{$class_name}.php");
}
However, apparently that function has been superseded:
http://www.php.net/manual/en/function.spl-autoload-register.php

Related

Overwriting class via composer

I'm using a composer Library, with lots of classes. There is one class (Alibrary\FileA) in this which doesn't do exactly what I want it to do.
namespace Alibrary;
class FileA
{
public function sayHello()
{
echo 'hello';
}
}
So I've written a replacement called Mylibrary\FileB. As you can see it's so must better.
namespace MyLibrary;
use \Alibrary\FileA;
class FileB extends FileA
{
public function sayHello()
{
echo 'hi';
}
}
Is there any way to tell Composer to load FileB every time FileA is asked for? I just want to replace one class, basically for testing purposes. I don't want to create a whole new repo - I've looked at https://getcomposer.org/doc/04-schema.md#replace already.
Is there something like this that I can do?
"classmap": [
"\Alibrary\FileA": "MyLibrary\FileB"
],
Thanks.
Your question has not very much to do with Composer in particular, but with how PHP works in general - and the code you are using.
Autoloading gets the name of the class that is still unknown to PHP and has to find the code that defines this class. But the situation you are facing would be the same if all classes are in one single file: The code is using class \Alibrary\FileA, and is not using class \MyLibrary\FileB. Note that your invented class names do suggest you are thinking in files, which is not the primary effect. Yes, classes' code is usually stored in files, but as soon as the code is loaded by PHP, it is only "the class" that is relevant, not where the code came from.
So you have some classes that do something, and one of them is \Alibrary\FileA. How can you change this to your own class? It depends. If the code creates that FileA class itself, you cannot override it from outside. If the code wants you to pass an instance of FileA as a parameter, you can instead pass your FileB class that inherits from FileA and must implement all that methods with the same parameter signature, and must return the same types. If it returns something completely different, it may work, but is likely to break.
Note that inheriting another class is in itself likely to break if you update the original library.

inheritance and external files. How do I go about it?

I have 3 files.
vehicleClass.php
motorbikeClass.php (extends vehicleClass)
index.php
My question is... How do I connect all 3. On my index page, do I have to have
include 'classes/vehicleClass.php';
Do I need to have an include for the motorbike class or will the extend (inheritence) cover this?
You can let php autoload your files, by registering your own autoload function. If you have, in example, all your class files in the directory DOCROOT . 'classes' (DOCROOT being your document root), you can use a function like this (example):
function class_loader($class) {
include DOCROOT . 'classes/' . $class . '.class.php';
}
spl_autoload_register('class_loader');
Now if you try to create an object of class 'foo', it will try to include the file DOCROOT . '/classes/foo.class.php' before creating the object. You might want to extend the function a bit, eg. to lowercase file names (include DOCROOT . 'classes/'. strtolower($class) .'.class.php';). This way you can place class Foo in foo.class.php.
Short answer: a class that is extending (or otherwise using) another class must already have defined the parent class before the definition of the child class. Your assumption is correct, your VehicleClass must be included (or better, require'd) prior to your definition of MotorBike class.
However, most frameworks don't go about and include every depedency before all class definitions. This would become unwieldy on any system that has any amount of complexity to it. Instead, the developers of PHP have provided methods for autoloading classes. Using spl_autoload_register will allow you to write a function that will attempt to load in the source file for a given class whenever it is referenced but a definition for it has not yet been found.
Furthermore, once you get a system together that becomes complex, you don't want to store all of your files in a single place. Most frameworks leverage the filesystem and namespaces to help better organize all of their classes. Because of this, the PSR-0 standard was developed in order to help facilitate autoloading between frameworks. Take a look at this question for examples of PSR-0 compliant autoloaders.
Example of PSR-0 compliant class:
<?php namespace Vendor\Package;
class ClassName { }
This file would live in the filesystem at /Vendor/Package/ClassName.php
What you have to do is include 2 files in the index.php.
For example, your index.php page could be something like this.
<?php
require 'classes/vehicleClass.php';
require 'classes/motorbikeClass.php';
// Assuming your class name is MotorBike
$motorBike = new MotorBike();
// And just call the method you want, for example If you have a method called bikeName
echo $motorBike->bikeName();
?>
I hope you get an idea now.
P/S: I prefer require over include. :) Include() should work fine too.

How to include a class in CakePHP 2.x

This is a very basic question but I can't figure it out.
I have a class that could be named myClass.php, this is a standalone PHP script that contains a standard object definition like this:
<?php
class myClass
{
public function myFunction($param1, $param2){
return $param1*$param2;
}
}
All I want to do is to be able to call to this class from a model, this is from App/Models/MyModel.php be able to simply do $myClass = new MyClass();
Where should I store myClass.php in the file structure and how can I make it visible for MyModel?
Thanks!
You'll note that you have a 'vendors' directory inside the root (ie, on the same level as the 'app' folder). This is for placing non-CakePHP related files that are shared across applications. You also have an 'app/Vendor' directory, which is for storing non-CakePHP files that are specific to that one app.
So, it should go in one of these two directories - most likely, in app/Vendor.
There's a little bit to know about loading vendor files - you can read the details here.
In your case, you probably just need:
App::uses('myClass', 'Vendor');

Including Custom Classes

I've just installed Symfony 2 and I'm looking at including my own classes into my project, but am having trouble getting the results I am after.
I'd like a controller to be able to call "MyClass.php" and run functions from it without the use of includes. After a bit of searching, it seems that classes need to be placed within a specific folder for them to be picked up automatically and used by the 'app'. I currently believe it to be the "lib" folder within the project bundle root.
At the moment my project sits within src/Bundle/ProjectBundle.
I have tried storing the Test class within Test.php inside ProjectBundle/lib, and have tried naming it 'Test.php' and Test.class.php, but my controller is still unable to find the file/class.
Where do I place my class files?
How should I name my class files? (aside from the standard naming conventions)
Am I barking up the wrong tree completely?
edit: The class to be called.
<?php
class Test
{
public function callMe()
{
return "FUNCTION 1 SUCCESSFULLY CALLED";
}
}
?>
You can do the following. Place the class in a sub-directory of your project and in the controller use use to register the namespace like this:
// the last part is the class name you want to include
use Vendor\BundleNameBundle\Utility\Factory;
The class would be located in: src/Vendor/BundleNameBundle/Utility/Factory.php.

PHP class file link issues?

I stated implementing object oriented design into my website. I'm using php, and ran into an issue.
As is my tendency, I like to define one class per one file - nothing else. Normally, if I remember correctly, in most languages classes can be called if they're in the same directory without having to be explicitly linked to the main program (I could be wrong, or unique to virtual machines).
Right now, php sends errors when I don't link the class file to the main file. On top of that, a child class won't execute unless I define the link to the parent's class file.
Do I have to explicitly link all of my files together?
Here's some snippets of my code for detail:
<?php
include_once 'VRC_Header2.php';
include_once 'UserService.php'; //Child class file of DB_MySQL.php
include_once 'DB_MySQL.php'; //Parent class
//Without the two links above, this file will not execute
Then the child class:
class UserService extends DB_MySQL
{...
Any help is appreciated.
Yes, in PHP, you have to include all classes you need before you instanciate them.
One method to circumvent this is to use autoloading:
http://php.net/manual/en/language.oop5.autoload.php
Which is used on most PHP Frameworks (e.g. Zend Framework).
You have to include all class files to one another. Otherwise other pages will not understand where the class is present.
You can use namespace concept.
http://php.net/manual/en/language.namespaces.php
But in this you have to include the class files.

Categories