Nusoap accessing $this inside method - using $this when not in object context - php

I have a nusoap class, with some methods defined in the constructor. The problem I'm having however, is calling a method either from a model I loaded or a method defined in the same class out of the constructor. The error I get is "Using $this when not in object context". None of the methods are static, so I'm not sure why it's having trouble accessing this. For reference, here is an example of what I'm trying to do.
edit: This is my first time working with nusoap, and the methods were defined in the constructor in all the examples I saw. If the methods do not need to be defined in the constructor, where do I define them?
class MySoapServer extends CI_Controller {
function __construct() {
parent::__construct();
//where I'm loading all my models and libraries,
//creating a new instance of soap server
//and registering all my methods
function myFunction() {
$this->testFunction() //this is where it errors out
}
}
function testFunction() {
return true;
}
}

Your function is in another function, it should look like:
class MySoapServer extends CI_Controller {
function __construct() {
parent::__construct();
//where I'm loading all my models and libraries,
//creating a new instance of soap server
//and registering all my methods
}
function myFunction() {
$this->testFunction() //this is where it errors out
}
function testFunction() {
return true;
}
}
What you seem to be trying to do is run testFunction() in the constructor? If that's the case then myFunction() isn't needed and you just need to add $this->testFunction() at the end of the constructor.
Like this:
class MySoapServer extends CI_Controller {
function __construct() {
parent::__construct();
//where I'm loading all my models and libraries,
//creating a new instance of soap server
//and registering all my methods
$this->testFunction();
}
function testFunction() {
return true;
}
}

I'm Not an expert on nusoap but PHP does not handle nested function very well. Why would you declare "myFunction" inside of the constructor? Try removing the nested function out of the constructor. Also, you might want to try and set the access modifiers of the function.

Related

Unexpected inheritance behavior of php code

I've written this code for check behavior of my app and i don't why this code works. I have 2 classes and 1 entry point
PHP 7.2
class Base{
public function check(){
return $this->checkUnexist();
}
}
class Main extends Base
{
public function checkUnexist()
{
return 'UNEXIST METHOD CALLED';
}
}
$main = new Main();
echo $main->check();
Expected result something like called method unexist. But it calls method from child class with "this". Why? And where i can read about this issue ?
Trying to access child values from base(parent) class is a bad design. What if in the future someone will create another class based on your parent class, forget to create that specific property you are trying to access in your parent class?
As per my understanding, When you extend the class the child class have all the property, methods available for the Main class object, which are accessible outside the class.
So when you created an object of Main class your class internally looks like
class Main
{
public function checkUnexist()
{
return 'UNEXIST METHOD CALLED';
}
public function check(){
return $this->checkUnexist();
}
}
the check method exists and you will get the response. Try to make the method checkUnexist private or protected you will see the difference.

Codeigniter, why do I need CI_Controller's construct?(code below)

Why do I need to use the parent::__construct(); constructor, what does it have I need?
//CONTROLLER
class users_ctrl extends CI_Controller {
function __construct() {
parent::__construct(); //Why do I need to include it?
$this->load->model('select_model');
}
public function index()
{
$data['user_list'] = $this->select_model->get_all_users();
$this->load->view('show_users', $data);
}
}
//MODEL
class select_model extends CI_Model{
function __construct() {
parent::__construct();
}
function get_all_users()
{
$query = $this->db->get('students');
return $query->result();
}
}
In your given examples, you are calling the load class that the base controller class loads. Without the parent's constructor, you would have to load an instance of it yourself.
As for your model, you would have to manually load your db object.
Remove it and you should get something like called to undefined propery $class::load
CodeIgniter aside, it really is a basic fundamental of object-oriented programming.
If you make a class that extends another, and you declare a new constructor in the child class, the parent constructor will never run - since you've overridden it, and since CodeIgniter base controller does (most likely) a lot of things behind the scenes, if you do not run parent constructor, your controller most likely won't be injected in CI's container.

what is $this->load->view() in CodeIgniter

$this is use for current class and view is method but what is load. Is this a property?
Is this example correct?
class super{
public $property;
public function superf1()
{
echo "hello";
}
public function col()
{
$this->superf1();
}
$this->property->super1();
}
Yes, load is a property.
Think of it like this:
class Loader {
public function view() {
//code...
}
}
class MyClass {
private $load;
public __constructor() {
$this->load = new Loader();
}
public someMethod() {
$this->load->view();
}
}
This syntax is called chaining.
Your controller inherits CI_Controller. So, if you look in application/system/core/Controller.php you'll find something interesting : $this->load =& load_class('Loader', 'core'); (l.50 with CI2). So, $this->load refer to the file application/system/core/Loader.php which have a function public function view (l.418 with CI2)
In the context of a class that extends CI_Controller (in other words: a controller) the symbol $this is the Codeigniter "super object". Which is, more or less, the central object for CI sites and contains (among other things) a list of loaded classes. load is one of the classes you'll always find there because it is automatically loaded by the CI system.
Technically, the class creates objects of the type CI_Loader. view() is just one of the many methods in the load class. Other commonly used class methods are model(), library(), config(), helper(), and database(). There are others.
So, in short, load is a class used to load other resources.
load is a class belongs to the loader class
codeigniter official documentation
view, model and others are methods
In PHP 8.1
use return("viewname", $data)

why do we still need parent constructor when controller class extends a parent controller?

I'm a beginner in CodeIgniter and OOP. I was reading a page of CI tutorial here. I found something that made a question in my mind.
Look at this code:
<?php
class News extends CI_Controller {
public function __construct()
{
parent::__construct();
$this->load->model('news_model');
}
I think if we made a class that extends CI_Controller, we assume it must have all methods and properties in its parent class (Although we can override them). So, why there is parent::__construct(); in the code?
__construct() is the constructor method of a class. It runs if you declare a new object instance from it. However, if a class implemented its own __construct(), PHP would only run the constructor of itself, not of its parent. For example:
<?php
class A {
public function __construct() {
echo "run A's constructor\n";
}
}
class B extends A {
public function __construct() {
echo "run B's constructor\n";
}
}
// only B's constructor is invoked
// show "run B's constructor\n" only
$obj = new B();
?>
In this case, if you need to run class A's constructor when $obj is declared, you'll need to use parent::__construct():
<?php
class A {
public function __construct() {
echo "run A's constructor\n";
}
}
class B extends A {
public function __construct() {
parent::__construct();
echo "run B's constructor\n";
}
}
// both constructors of A and B are invoked
// 1. show "run A's constructor\n"
// 2. show "run B's constructor\n"
$obj = new B();
?>
In CodeIgniter's case, that line runs the constructor in CI_Controller. That constructor method should have helped your controller codes in some way. And you'd just want it to do everythings for you.
To answer your question directly from the Code Iginiter documentation:
The reason this line is necessary is because your local constructor will be overriding the one in the parent controller class so we need to manually call it.
http://ellislab.com/codeigniter/user-guide/general/controllers.html#constructors
Extension used for all classes.
__construct() used for that class that you use.
Classes which have a constructor method call this method on each newly-created object, so it is suitable for any initialization that the object may need before it is used.
I believe the need of calling the parent constructor/method is a code smell, known as Call super. Besides the error-sensitivity (forgetting this call, you can get unexpected results), it's procedural instead of OOP. After all, the order of statements can lead to unexpected results too.
Read more here: https://martinfowler.com/bliki/CallSuper.html
Inheritance is being used via the keyword extends. The parent class could be setting some values when its constructor is being called. If the parent constructor is not called the values are not set and the child class will not get those values.
Example:
class Super {
protected $a;
public function __construct(){
$this->a = 'Foo';
}
}
class Child extends Super{
protected $b = 'Bar';
public function __construct() {
parent::__construct();
echo $this->a;
}
}
$x = new Child();
Here, the class Child would echo out nothing if the parent constructor was not called.
So in Codeigniter the parent class is probably setting some values that are of help to its children when you call its constructor and those values are only available to its children if the parent constructor is called.

Using CodeIgniter libraries through static methods

I am having trouble trying to call CodeIgniter methods in my static functions, just using $this doesn't work because its not in object context, the static keyword doesn't work either. This an example of the code in my core model, the $table variable is successfully defined from another model like posts.
class MY_Model extends CI_Model {
protected static $table;
public function __construct() {
parent::__construct();
}
public static function find_all() {
$this->db->select('*');
$sql = $this->db->get(static::$table);
return $sql->result();
}
}
If $this doesn't work you can get around this like this:
$CI =& get_instance();
$CI->db->...
The codeigniter built in loader class automatically instantiates the class. There is no support to use classes without instantiating. You can manually include your file in the model file then you can use it. For more details check out this thread:
http://codeigniter.com/forums/viewthread/73583/
What you want is a refence to the static var in the class, so use:
class MY_Model extends CI_Model {
protected static $table;
public function __construct() {
parent::__construct();
}
public static function find_all() {
$this->db->select('*');
$sql = $this->db->get(self::$table);
return $sql->result();
}
}
And, of course, $table does need to have a value!
Codeigniter doesn't generally support static methods I believe and they are really an attempt to shoehorn procedural code into object oriented code.
Anyway, I think your best bet is to either use the class without static methods, or turn your code into a "helper". A helper is just an old school function library. You would create it under the helpers folder and it can be loaded with $this->load->helper('helper_name'). You can then call the function as in normal procedural code, in other words 'find_all()'
Hope this helps.
First time contributor :)

Categories