I have the following scenario:
Controller:
class Collect extends CI_Controller {
function __construct() {
parent::__construct();
$this->load->library('phirehose');
$this->load->library('oauthphirehose');
$this->load->library('ghettoqueuecollector');
}
function index() {
// Start streaming/collecting
$this->ghettoqueuecollector('datos');
...
}
Class:
A)
class Ghettoqueuecollector extends Oauthphirehose {
...
}
B)
abstract class Oauthphirehose extends Phirehose {
...
}
C)
abstract class Phirehose {
...
}
When I try to use the controller gives this error:
"Fatal error: Cannot instantiate abstract class Phirehose"
That is lacking adapt? Codeigniter outside these classes work using require. Can I use them in CI? Thanks
$this->load->library() is made to include, instantiate and configure classes, it's not just an alias for require() - you can't use it in that manner.
If you need to extend an abstract class, you'll have to manually include/require it from the file that extends it, like this:
libraries/Oauthphirehose.php:
require_once __DIR__.'/Phirehose.php';
abstract class Oauthphirehose extends Phirehose {}
libraries/Ghettoqueuecollector.php:
require_once __DIR__.'/Oauthphirehose.php';
class Ghettoqueuecollector extends Oauthphirehose {}
Then you just load the one library that you actually need to instantiate:
$this->load->library('ghettoqueuecollector');
Related
I'm hoping somebody out there can help me. I am using laravel 4 and I'm writing my first unit tests for a while but am running into trouble. I'm trying to extend the TestCase class but I'm getting the following error:
PHP Fatal error: Class registrationTest contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Illuminate\Foundation\Testing\TestCase::createApplication) in /home/john/www/projects/MyPainChart.com/app/tests/registrationTest.php on line 4
Now if I have this right then the error is referring to the fact that is a method is abstract then the class it's in must also be abstract. As you can see from below the TestCase class it is abstract. I have searched for this error but have drawn a blank.
Trying to follow this cast on Laracasts https://laracasts.com/lessons/tdd-by-example and although you have to be a subscriber to watch the video the file is underneath it and as you can see I am doing nothing different to Jeffrey Way.
My Test:
<?php
class registrationTests extends \Illuminate\Foundation\Testing\TestCase
{
/**
* Make sure the registration page loads
* #test
*/
public function make_sure_the_registration_page_loads_ok()
{
$this->assertTrue(true);
}
}
The beginning of the TestCase class:
<?php namespace Illuminate\Foundation\Testing;
use Illuminate\View\View;
use Illuminate\Auth\UserInterface;
abstract class TestCase extends \PHPUnit_Framework_TestCase {
By the way - the Laravel testing class is not autoloaded by default and so I have tried both the fully qualified class name and use Illuminate\Foundation\Testing and then just extending TestCase. I know it can see it aswhen I don't fully qualify the name it complains that the class cannot be found. I've also tried:
composer dump-autoload
and
composer update
Any help appreciated
According to your error message: Class registrationTest contains 1 abstract method the Base Class contains an abstract method and when a Child Class extends another class with abstract methods then the child class should implement the abstract methods available in Base class. So, registrationTest is child class and \Illuminate\Foundation\Testing\TestCase is the base class and it contains an abstract method:
An abstract method in \Illuminate\Foundation\Testing\TestCase:
abstract public function createApplication();
So, in your child class/registrationTest you must implement this method:
public function createApplication(){
//...
}
But, actually you don't need to directly extend the \Illuminate\Foundation\Testing\TestCase because in app/tests folder there is a class TestCase/TestCase.php and you can extend this class instead:
// In app/tests folder
class registrationTest extends TestCase {
//...
}
The TestCase.php class looks like this:
class TestCase extends Illuminate\Foundation\Testing\TestCase {
public function createApplication()
{
$unitTesting = true;
$testEnvironment = 'testing';
return require __DIR__.'/../../bootstrap/start.php';
}
}
Notice that, TestCase has implemented that abstract method createApplication so you don't need to extend it in your class. You should use TestCase class as base class to create test cases. So, create your tests in app/tests folder and create classes like:
class registrationTest extends TestCase {
public function testBasicExample()
{
$crawler = $this->client->request('GET', '/');
$this->assertTrue($this->client->getResponse()->isOk());
}
}
Read Class Abstraction.
Firstly go in composer.json and add
"scripts" : {"test" : "vendor/bin/phpunit"
}
Then run composer update
Then
The TestCase.php class in path /test/ should look like
<?php
namespace Tests;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
use Illuminate\Support\Facades\Artisan;
abstract class TestCase extends BaseTestCase {
use CreatesApplication;
}
Then your registrationTests class should look like this
<?php
namespace Tests\Feature;
use Tests\TestCase;
class registrationTests extends TestCase {}
Just intake dependancy at the top of your class as follows and you are good to go,
<?php
namespace YOUR_CLASS_PATH;
use Tests\TestCase;
class UserTest extends TestCase{
...//your business logic here
}
I hope this works.
I have a relatively simple question. I am trying to inherit a constructor from a php superclass to authenticate on this controller.
Here is my super class:
class Auth_Controller extends CI_Controller {
function __construct()
{
parent::__construct();
if(!session_id()){
session_start();
}
$this->load->view('login_v/logincheck');
}
}
and here is my subclass:
class Event_Controller extends Auth_Controller {
function __construct()
{
parent::__construct();
}
public function get_events_by_owner() {
$this->load->model('Event_model');
$data['events'] = $this->Event_model->select_by_owner($_SESSION['SignedIn']);
$this->load->view('event_view', $data);
}
}
This is not working. only a white page is rendered. I'm not sure why it isn't working. If I move the constructor from Auth_Controller to Event_Model this works.
Thanks!
EDIT:
Fatal error: Class 'Auth_Controller' not found in
../controllers/event_controller.php on line 12
Your solution is not going to work, you should try either:
Move this code:
if(!session_id()){
session_start();
}
$this->load->view('login_v/logincheck');
to a cutom library, than run this library within constructor of your controller. Please read Creating Libraries for details.
or:
Create MY_Controller class and put auth code (quoted above) into its constructor. Than you'll be able to extend like:
class Event_Controller extends MY_Controller {
(...)
Please read Creating Core System Classes for details.
I'm working on a Symfony2 project. For useful technical pratictes, I need to import external libraries. So I did it. But this library creates somes *_Exception class who extend from Exception.
My external library file ends with:
class CloudKey_Exception extends Exception {}
class CloudKey_RPCException extends CloudKey_Exception {public $data = null;}
class CloudKey_ProcessorException extends CloudKey_RPCException {}
class CloudKey_TransportException extends CloudKey_RPCException {}
class CloudKey_SerializerException extends CloudKey_RPCException {}
class CloudKey_AuthenticationErrorException extends CloudKey_RPCException {}
class CloudKey_RateLimitExceededException extends CloudKey_AuthenticationErrorException {}
class CloudKey_InvalidRequestException extends CloudKey_RPCException {}
class CloudKey_InvalidObjectException extends CloudKey_InvalidRequestException {}
class CloudKey_InvalidMethodException extends CloudKey_InvalidRequestException {}
class CloudKey_InvalidParamException extends CloudKey_InvalidRequestException {}
class CloudKey_ApplicationException extends CloudKey_RPCException {}
class CloudKey_NotFoundException extends CloudKey_ApplicationException {}
class CloudKey_ExistsException extends CloudKey_ApplicationException {}
class CloudKey_LimitExceededException extends CloudKey_ApplicationException {}
And when I try to instance my object in controller, Symfony returns this:
Fatal error: Class 'CD\DMBundle\Entity\Exception' not found in /var/www/carpediese/src/CD/DMBundle/Entity/CloudKey.php on line 513
I think Exception class is native PHP5+ class. How can I tell it to Symfony?
Remember to properly set the use statements in files which use the Exception class.
EDIT:
When you refer to any class in PHP 5.3+ just below the namespace declaration you need to add which namespaces you are using for the referenced class (or use the whole namespace when referencing the class). So, if the Exception class you are using belongs to say someLibrary\ClouKey\Exceptions\ namespace you should either have
use someLibrary\CloudKey\Exceptions\Exception;
at the beginning of the file, just below namespace, or use the whole namespace when defining your new class:
class CloudKey_Exception extends someLibrary\CloudKey\Exceptions\Exception {}
EDIT 2:
In the class you are using the Exception is indeed the native PHP class so \Exception should be used. The error you get is generated by this part of the CloudKey class:
public function __get($name)
{
if (!isset($this->objects[$name]))
{
$class = 'CloudKey_' . ucfirst($name);
if (!class_exists($class))
{
$class = 'CloudKey_Api';
}
$this->objects[$name] = new $class($this->user_id, $this->api_key, $this->base_url, $this->cdn_url, $name, $this->proxy, $this->timeout);
$this->objects[$name]->parent = $this;
}
return $this->objects[$name];
}
According to the documentation (http://php.net/manual/en/language.oop5.basic.php):
If a string containing the name of a class is used with new, a new instance of that class will be created. If the class is in a namespace, its fully qualified name must be used when doing this.
So you have to edit the quoted part of the code to use the whole namespace inside the string for the class name.
I created a base_model extends CI_Model class and put it in application/model. Then, I created another class that extends base_model, but I get the following error:
Cannot find this class
Other resources told me to put the base_model in:
application/core
or:
application/libraries
However, I would like to put it in application/models for convenience. Can I put this class in application/models and still have it work correctly?
Try putting a MY_Model class in your application/core folder instead. First-level inheritance was built into CI by default, i.e.:
{APPATH}/core/MY_Model.php:
<?php
class MY_Model extends CI_Model {
public function __construct()
{
parent::__construct();
}
}
In that same file, if you want alternate parent classes, try:
...
class Base_model extends MY_Model {
public function __construct()
{
parent::__construct();
}
}
...
If you don't put it in MY_Model, YOU ARE RESPONSIBLE for loading the base model first (before an extended class references it), AND you can't have a file in your models/ folder called Base_model.php, for example.
I have strictly followed the how-to article by Phil Sturgeon, to extend the base controller. But I get still some errors.
My 3 classes:
// application/libraries/MY_Controller.php
class MY_Controller extends Controller{
public function __construct(){
parent::__construct();
}
}
// application/libraries/Public_Controller.php
class Public_Controller extends MY_Controller{
public function __construct(){
parent::__construct();
}
}
// application/controllers/user.php
class User extends Public_Controller{
public function __construct(){
parent::__construct();
}
}
Fatal error: Class 'Public_Controller' not found in /srv/www/xxx/application/controllers/user.php on line 2
Curious is that the following snippet is working, if I directly extends from MY_Controller:
// application/controllers/user.php
class User extends MY_Controller{
public function __construct(){
parent::__construct();
}
}
I have loaded the controllers via __autoload() or manually. The controllers are loaded succesfully.
CI-Version: 1.7.3
You need to require the Public Controller in your MY_Controller
// application/libraries/MY_Controller.php
class MY_Controller extends Controller{
public function __construct(){
parent::__construct();
}
}
require(APPPATH.'libraries/Public_Controller.php');
You get the error because Public_Controller was never loaded. Doing this would allow you to extend from Public_Controller
I like what you are doing because I do that all the time.
You can do this also in your MY_Controller when you want to create an Admin_Controller
// application/libraries/MY_Controller.php
class MY_Controller extends Controller{
public function __construct(){
parent::__construct();
}
}
require(APPPATH.'libraries/Public_Controller.php'); // contains some logic applicable only to `public` controllers
require(APPPATH.'libraries/Admin_Controller.php'); // contains some logic applicable only to `admin` controllers
You should place Public_controller in with MY_Controller inside MY_Controller.php
// application/libraries/MY_Controller.php
class MY_Controller extends Controller{
public function __construct(){
parent::__construct();
}
}
class Public_Controller extends MY_Controller{
public function __construct(){
parent::__construct();
}
}
I use __construct everywhere and it works fine I recently wrote up an article on how to do this in relation to wrapping your auth logic into your extended controllers. It's about half way down when I start discussing constructing your controllers.
Problem was solved here: http://devcrap.net/pl/2011/09/04/codeigniter-dziedziczenie-z-my_controller-extends-my_controller/. In polish but code is good :]
I had problem like this,After some search I found error was made myself,Because my controller class name was MY_Controller but file name was My_Controller[Case not matching].
Note:- In localhost I didnt have any error.
In extended controller I Use
class Home extends MY_Controller{
function __construct() {
parent::__construct();
}
}
even I got the error.
After changing my file name to MY_Controller it started to work well.
I have a custom controller class called MY_Controller it extends CI_Controller and it works fine. It is located at application/core and it has custom functions lo load views in my site.
I use an abstract class My_app_controller that extends MY_Controller for my_app specific behabior, I want every controller in my_app to extend this abstract class. (I use diferent apps in the site, so some apps will extend My_app_controller and other apps will extend My_other_apps_controllers)
But when I try to extend My_app_controller from any controller in my application, "Main_app_controller extends My_app_controller" generates a Class 'My_app_controller' not found exception.
I found two solutions:
use include_once in Main_app_controller.php file.
include_once APPPATH.'controllers/path/to/My_app_controler.php';
break the "one class per file" rule of code igniter and define my My_app_controller just in the same file MY_Controller is (under application/core).
Manual says:
Use separate files for each class, unless the classes are closely
related
Well... they are.
Anyway, I prefered to use the include_once solution as I think it is better to have one file per class and My_app_controller is located under application/controllers/my_app folder. (so application/controllers/other_apps will exist)