I have the Module_One in which function exampleOne()...
class Model_One extends CI_Model {
function __construct()
{
parent::__construct();
}
function exampleOne(){
return "test";
}
}
I wonder how, (if that is possible), call the Model_One within Model_Two...
class Model_Two extends CI_Model {
function __construct()
{
parent::__construct();
}
function exampleTwo(){
return "testTwo";
}
}
In a way that I could just call the Model_Two and use the exampleOne() of Model_One.
class Controller_One extends CI_Controller{
function index(){
$this->load->model('Model_Two');
$this->Model_Two->exampleOne();
}
}
I know I could do it that way ...
class Model_One extends CI_Model {
function __construct()
{
parent::__construct();
}
function exampleOne(){
return "test";
}
}
and so ...
class Model_Two extends CI_Model {
function __construct()
{
parent::__construct();
$this->load->model('Model_One');
}
function exampleTwo(){
return "testTwo";
}
function exampleOne2(){
$this->Model_One->exampleOne();
}
}
and so ...
class Controller_One extends CI_Controller{
function index(){
$this->load->model('Model_Two');
$this->Model_Two->exampleOne2();
}
}
However, redundant create a function to call another function, I know it must have another way to do this, but I do not know, and found nothing upon. anyone any ideas?
Thanks for your attention
yeah, Programming should DRY (Dont Repeat Yourself).
for your case, try this code :
class Model_Two extends CI_Model {
function __construct()
{
parent::__construct();
$this->load->model('Model_One');
}
function exampleTwo(){
return "testTwo";
}
// change this method to the name of the another module
function model_one(){
// just return the new model object
// so you can keep using all method in this object, without repeat the methods
return $this->Model_One;
}
}
and in your controller, you use the model_two model like this :
class Controller_One extends CI_Controller{
function index(){
$this->load->model('Model_Two');
$this->Model_Two->model_one()->exampleOne();
// and here you can use all method from model_one...
// $this->Model_Two->model_one()->exampleTwo();
}
}
I hope this help for you. :)
Related
I am setting session variable in function of a controller like below.
use Illuminate\Support\Facades\Session;
class UserController extends Controller
{
public function store(Request $request)
{
session(['user_name' => $user_name]);
}
}
I am trying to access that session variable in another function of another controller.
use Illuminate\Support\Facades\Session;
class DashboardController extends Controller
{
public function __construct()
{
dd(session('user_name')); // I am not getting value here
}
}
I am not getting value from Session Variable.
You can do it like this
use Illuminate\Support\Facades\Session;
class UserController extends Controller
{
public function store(Request $request)
{
session()->put('user_name', $user_name);
}
}
And you can get it another controller or anywhere like this
session()->get('user_name');
Hope this will help you, thanks..
I am trying to call a parent method from its child which has the same method name. Doing so results in a strict standards error. There's an easy solution of renaming the child method. However, is there a way to keep the names of the two methods identical without a standards warning? Thanks.
Strict standards: Declaration of Child::getContentFromDb() should be compatible with Parent::getContentFromDb($id) in /foo/Child.class.php on line xxx
Pseudo-code example:
class Parent {
protected function getInfoFromDb($id) {
return $infoFromDb;
}
}
class Child extends Parent {
public static $id = xx;
public $info = array();
public function __construct() {
$this->info = $this->getInfoFromDb();
}
public function getInfoFromDb() {
// the line below causes the problem
return parent::getInfoFromDb(self::$id);
}
}
Your method override should take the same parameter list as the one you are overriding.
e.g.
class ParentClass {
protected function getInfoFromDb($id) {
return "INFO FROM DB:" . $id;
}
}
class Child extends ParentClass {
public static $id = "xx";
public $info = array();
public function __construct() {
$this->info = $this->getInfoFromDb();
}
/**
* #param specific ID, or do not set for default action.
* #return string
*/
public function getInfoFromDb($id = false) {
return parent::getInfoFromDb(self::$id);
}
}
I'm trying to follow along with a C# design patterns book by writing my code in TypeScript. Perhaps this is my first mistake, but it's a way I enjoy to learn a language.
TypeScript doesn't support the abstract keyword for classes, so I am trying to simulate it. Maybe this is my second mistake.
Here is my interface and classes:
interface IEngine {
getSize(): number;
getTurbo(): boolean;
}
class AbstractEngine implements IEngine {
constructor(private size: number, private turbo: boolean) {
throw "Abstract class";
}
public getSize(): number {
return this.size;
}
public getTurbo(): boolean {
return this.turbo;
}
public toString(): string {
var funcNameRegex = /function (.{1,})\(/;
var results = (funcNameRegex).exec(this.constructor.toString());
var className = (results && results.length > 1) ? results[1] : '';
return className + " (" + this.size + ")";
}
}
class StandardEngine extends AbstractEngine {
constructor(size: number) {
// not turbo charged
super(size, false);
}
}
When trying to instantiate an AbstractEngine with new AbstractEngine(1, true) I get an "Abstract class" error as expected.
When trying to instantiate a StandardEngine with new StandardEngine(9000) I also get an "Abstract class" error.
Is there a way I can simulate an abstract class in TypeScript, have it unable to be instantiated, but still call super in a class that extends it? And what about simulating abstract methods, can I protect those and still call the super method?
As of today, TypeScript 1.6 is live and has support for the abstract keyword.
abstract class A {
foo(): number { return this.bar(); }
abstract bar(): number;
}
var a = new A(); // error, Cannot create an instance of the abstract class 'A'
class B extends A {
bar() { return 1; }
}
var b = new b(); // success, all abstracts are defined
I advise you not to do that. When the TypeScript compiler will implement a mechanism for abstract function, it is time to use it. But hacks that work at runtime are incomprehensible and degrade performance.
The interfaces are the great strength of TypeScript. They should be used massively.
Your example should be written like this:
interface Engine {
getSize(): number;
getTurbo(): boolean;
}
class StandardEngine implements Engine {
constructor(private size: number, private turbo: boolean) {
}
public getSize(): number {
return this.size;
}
public getTurbo(): boolean {
return this.turbo;
}
}
The simplest solution is often the best.
If you want to reuse code without a parent class which would then necessarily usable, the Handbook suggests Mixins. Mixins are a way of coping skills from several distinct entities.
Or with modules it is possible to keep private implementation (and therefore organize it as you want it) and export only interfaces and factories. An example:
module MyEngineModule {
export interface Engine {
getSize(): number;
getTurbo(): boolean;
}
export interface StandardEngine extends Engine {
}
export function makeStandardEngine(size: number, turbo: boolean): StandardEngine {
return new ImplStandardEngine(size, turbo);
}
// here classes are private and can inherit or use mixins…
class ImplEngine {
constructor(private size: number, private turbo: boolean) {
}
public getSize(): number {
return this.size;
}
public getTurbo(): boolean {
return this.turbo;
}
}
class ImplStandardEngine extends ImplEngine implements StandardEngine {
}
}
console.log(MyEngineModule.makeStandardEngine(123, true).getSize());
When calling the StandardEngine constructor, you have a call to super(size, false). This call into the base class is what is generating the second "Abstract class" error.
To simulate an abstract base class that will throw when instantiated, create an Init function that is called from your derived class.
class AbstractEngine implements IEngine {
private _size: number;
private _turbo: boolean;
constructor() {
throw "Abstract class";
}
init(size:number, turbo: boolean) {
this._size = size;
this._turbo = turbo;
}
}
class StandardEngine extends AbstractEngine {
constructor(size: number) {
// not turbo charged
// do not call super here
init(size, false);
}
}
An alternative solution would be to user a property that if set indicates that the constructor is being called from a child class it is safe to continue. This is shown below :
class AbstractEngine {
safe; // IMPORTANT : do not initialize
constructor(private size: number, private turbo: boolean) {
if(!this.safe) throw "Abstract class"; // IMPORTANT
}
}
class StandardEngine extends AbstractEngine {
constructor(size: number) {
this.safe = true; // IMPORTANT
super(size, false);
}
}
How do you implement interface for external package in Laravel? Say, I want to use Mashape/Unirest API to get analyse of text, but in future I would like to switch to other API provider and do not change to much in code.
interface AnalyzerInterface {
public function analyze(); //or send()?
}
class UnirestAnalyzer implements AnalyzerInterface {
function __constructor(Unirest unirest){
//this->...
}
function analyze($text, $lang) {
Unirest::post(.. getConfig() )
}
//some private methods to process data
}
And where to put that files interfece and UnirestAnalyzer? Make special folder for them, add to composer? Add namespace?
This is how I would go to Interface and Implement something like this:
interface AnalyzerInterface {
public function analyze();
public function setConfig($name, $value);
}
class UnirestAnalyzer implements AnalyzerInterface {
private $unirest;
private $config = [];
public function __construct(Unirest unirest)
{
$this->unirest = $unirest;
}
public function analyze($text, $lang)
{
$this->unirest->post($this->config['var']);
}
public function setConfig($name, $value)
{
$this->config[$name] = $value;
}
//some private methods to process data
}
class Analyser {
private $analizer;
public function __construct(AnalyzerInterface analyzer)
{
$this->analyzer = $analyzer;
$this->analyzer->setConfig('var', Config::get('var'));
}
public function analyze()
{
return $this->analyzer->analyze();
}
}
And you must bind it on Laravel:
App::bind('AnalyzerInterface', 'UnirestAnalyzer');
I would to override constroller constrcuter's like this :
class XControler extends AppController {
public $attr = null;
public __construct(){
$this->attr = new YController();
}
}
But when I do that I take error ! can you explain me why and how I do that with out using requestAction just OOP !
thanks
Controllers are responsible for dealing with end user requests. Each controller action should have a view, and normally you would not want to access the methods from YController inside XController.
What you want to achieve can be done this way:
XController.php
App::uses('YController', 'Controller');
class XController extends AppController {
public $attr;
public $uses = array('Person');
public function __construct($request = null, $response = null) {
$this->attr = new YController();
parent::__construct($request, $response);
}
public function method1() {
// you can now call methods from YController:
$this->attr->Ymethod1();
}
}
YController.php
class YController extends AppController {
public function Ymethod1() {
// ....
}
}
However, the business logic should be inside Models or Components. This is the proper way to share methods between more controllers.
So your XController should look like:
class XController extends AppController {
public $uses = array('Model1');
public function action1() {
$this->Model1->method1();
// ....
}
}