Welcome Guest, Not a member yet? Register   Sign In
Autoloaded Classes that Receive Values During Instantiation
#1

[eluser]Krumpet[/eluser]
I'm not sure if this problem represents my basic knowledge of CI or my basic knowledge of OOP. Hopefully, we'll find out...

What I'm trying to do is create a Fetch object to retrieve XML feeds. Users will be able to choose from a few different options to define the feed they want to return. Their choices are passed to the Search class where they are placed in a new Params object and then the Params object is passed into the Fetch class which will return the feed in array format - when I get this done.

Where I'm confused is with the Fetch __construct. First, is it 'good OOP form' to pass values into a class during object creation? Second, how is this approach affected by autoloading the class?

Here is the code for the Search class (poorly named, I know) and the Fetch class (incomplete). I've also included the error I'm getting. Thanks!

Code:
class Search extends CI_Controller{
    
    public function index()
    {
        $this->config->load('program');
        $this->load->library('params');
        $this->load->library('fetch');

        $params = new Params($_GET['username'],$_GET['feed'],$_GET['locale']);

        $fetch = new Fetch($params);
    }
}

Code:
class Fetch {
    
    protected $_url;
    protected $_remotefile;
    protected $_error;
    protected $_urlParts;
    
    public function __construct($params)
    {
        /*
        /    receive url, pass to setURL method and store in protected variable
        */
        $this->setURL($params);
        
        /*
        /    validate URL
        */
        $this->checkURL();
        
        /*
        /    check each connection option and choose between direct access, cURL access, or socket access
        */
        if (ini_get('allow_url_fopen')){
            $this->_remoteFile = getInstance('direct');
        } elseif (function_exists('curl_init')){
            $this->_remoteFile = getInstance('curl');
        } else {
            $this->_remoteFile = getInstance('socket');
        }
    }

The error I am getting is as follows:

A PHP Error was encountered

Severity: Warning

Message: Missing argument 1 for Fetch::__construct(), called in /Users/ryanodonnell/Sites/affiliates/system/core/Loader.php on line 950 and defined

Filename: libraries/Fetch.php

Line Number: 9
#2

[eluser]d1a8lo24[/eluser]
Not really sure if i'm right or not i'm not really good with OOP but that is why I love CI because it makes thing a lot easier.

I use some open source libraries and even though I know in a normal php script you always do the $var = new Class($params);

I like the way CI does it.

So in your code I think it should look like this.
Code:
class Search extends CI_Controller{
    
    public function index()
    {
        $this->config->load('program');
        $this->load->library('params');
        $this->load->library('fetch');

        $params = $this->parama($_GET['username'],$_GET['feed'],$_GET['locale']);

        $fetch = $this->fetch($params);
    }
}

Now for what i know I think that CI allows you to pass any parameters through an array and for what I remember in one of my apps I didn't pass an array and I was getting errors. Until I finally found how to do it.

You can also find this info in the users guide look for
Quote:Passing Parameters When Initializing Your Class
http://ellislab.com/codeigniter/user-gui...aries.html


If you still want use your code try the following it will probably work the way you expect it.

Code:
class Search extends CI_Controller{
    
    public function index()
    {
        $this->config->load('program');
        include('path/to/library/params');
        include('path/to/library/fetch');

        $params = new Params($_GET['username'],$_GET['feed'],$_GET['locale']);

        $fetch = new Fetch($params);
    }
}
#3

[eluser]InsiteFX[/eluser]
You need to assign a default value!
Code:
$this->load->library('fetch', $params);

// fetch class
public function __construct($params = array())

InsiteFX
#4

[eluser]Krumpet[/eluser]
Thanks for the help. I also saw what you are saying in the User Manual, but when I try it I must be making a mistake somewhere.

Here is what is happening...

I capture a few inputs from the URL using $_GET. I create a Params object to hold those values. I then pass the Params object into my Fetch object. THAT is where things fall apart. For one reason or another, the Fetch object will not accept the Params object when I attempt to pass it in.

The error I am getting is as follows...

A PHP Error was encountered

Severity: Notice

Message: Trying to get property of non-object

Filename: libraries/Fetch.php

Line Number: 37


However, I have verified the Params object exists and that it has those properties. I just can't seem to access them from the Fetch object - even though I've passed them in.

Thoughts?

My updated code is as follows...

Code:
<?php
class Search extends CI_Controller{
    
    public function index()
    {
        $this->config->load('program');
        $this->load->library('params');
        $params = new Params($_GET['username'],$_GET['feed'],$_GET['locale']);
        $this->load->library('fetch',$params);
    }
}

Code:
<?php
class Params
{
    public $username;
    public $feed;
    public $locale;
    
    public function __construct($username="picman",$feed="pc",$locale="en")
    {
        $this->username = $username;
        $this->feed = $feed;
        $this->locale = $locale;
        
    }
}

Code:
<?php
class Fetch {
    
    protected $_url;
    protected $_remotefile;
    protected $_error;
    protected $_urlParts;
    
    public function __construct($params = array())
    {
        $this->setURL($params);
        
    }

I've omitted some of the Fetch class as it is not relevant. Thanks!
#5

[eluser]InsiteFX[/eluser]
Try this, I think the problem is your passing an object when it is expecting an array!
Code:
<?php
class Search extends CI_Controller{
    
    public function index()
    {
        $this->config->load('program');
        $this->load->library('params');
        $params['username'] = $_GET['username'];
        $params['feed']     = $_GET['feed'];
        $params['locale']   = $_GET['locale'];
        $this->load->library('fetch',$params);
    }
}

InsiteFX
#6

[eluser]Krumpet[/eluser]
Hmmm...you make a good point and I'm pretty sure your method will work. However, I'm still curious how to pass an object into a class in CI. Any thoughts?
#7

[eluser]Krumpet[/eluser]
Ok, I've been able to call classes and pass in arrays. Thanks for the suggestion.

Let's say I'm at http://www.somewhere.com/calling/ and my Calling class needs to work with the Called library. I can do this as follows:

Code:
class Calling{
  public function index()
  {
    $foo = array();
    $this->load->library('called',$foo);
  }
}

Code:
class Called{
  public function __construct($foo = array())
  {
    whatever
  }
}

However, I don't always want to pass in an array. Sometimes I want to pass a string, sometimes an integer, and sometimes an object.

How can I create the Called class so it will accept different types of arguments?

EDIT: I've also verified I can put an object into an array and pass it to the Called class. Still wondering if CI requires everything to be passed in array form.
#8

[eluser]InsiteFX[/eluser]
Try this:
Code:
// change this:
$params = new Params($_GET['username'],$_GET['feed'],$_GET['locale']);
// to this:
$params = $this->params($_GET['username'],$_GET['feed'],$_GET['locale']);
And see if it works for you.

InsiteFX
#9

[eluser]Krumpet[/eluser]
Ok, I think my question is getting lost here so let me try to simplify...

I have successfully created Library classes and passed in arrays. However, how do I pass in a string or an integer? Whenever I try to setup the Library class __construct to accept a string either, I am told, "Missing argument 1 for Cache::__construct(), called in /Users/NAME/Sites/affiliates/system/core/Loader.php on line 950 and defined".

Why does CI always look for an array when instantiating a Library class? Does anyone know? Is my approach screwed up? It just seems crazy to me that I have to ALWAYS pass an array into a class. That can't be correct.
#10

[eluser]theprodigy[/eluser]
I think it is CI's way of allowing you to send any number of variables as parameters to your library. You can have none (by not passing in anything), all the way up to the number of elements in your array, and CI only ever has to worry about whether or not that array was passed in at all.




Theme © iAndrew 2016 - Forum software by © MyBB