Welcome Guest, Not a member yet? Register   Sign In
Using the URL to determine page content without making a function for each page
#1

[eluser]Unknown[/eluser]
Hi,

Apologies if this is simple or that Ive just got the wrong end of the stick but Ive only just started using OOP and CodeIgniter so am still a bit confused.

Basically Ive followed a tutorial and from that I have created a function within my controller that produces content.

The way this works is that the name of the function is in the URL like this

mydomain.com/controller/function

although I think they're called methods now not functions.

Anyway from this as an example I would need to make a method called 'function' within my controller.

What Im wanting is so I can have something like this:

mydomain.com/jobs/artist

I want to create it so that I can change the last part of the URL from artist to say electrician and then the controller (jobs) will fetch the data for electrician rather than artist.

At the moment the only way I can think of doing this would be to create a function for every possible job title and then have that search the database for the relevant data.

Is there a way to do this with just one function? Id like to keep the URLs as they are so they are search engine friendly.

Can anyone point me in the right direction?

Thanks






#2

[eluser]boltsabre[/eluser]
Sure, just create an array with all your job titles (you may want to isolate the array into a helper file so that way you can use the same array (thus preventing data integrity issues/bugs) across your application (for example, using the array also in your models). Then if you ever need to add to the array (or remove from it) it's just one array you need to update and hey presto, you're done!
(you can also create an associative array if you need to store more data than just the job type, for example, you may want to have an "active/inactive" status, etc)

Then in your controller it's something like this (pseudo code)
Code:
public function jobs(){
   //load your helper here, in your class constructor, or autoload it in your config file
   //call your helper function, which should return the array
   $jobs_array = $this->helper->return_array();
   if (in_array($jobs_array, $this->uri->segment(3)){
      //we know that the uri segment is a valid job, continue on with your stuff
   }else{
      // oh dear, for some reason the uri segment isn't a valid job... perhaps you typed a link wrong, forgot to add this job to the array, or the user has been playing around with the url, either way, it's not valid, redirect user to a 404 page or something.
   }
}

Anyway, that's the jist of it. Another option is to store all your jobs in a database table (a bit like how CMSs work (or xml file) and check for it that way.

If you are working on your own personal project, I'd just go with a helper file, it reduces a need to query the DB every time you call your function... but if you're working on a larger application with a back end / admin area where you want someone else to be able to add/edit/delete job titles, then you'd best go for the database solution.
#3

[eluser]Unknown[/eluser]
Ah thanks for that.

I will be using it in a large database project but I think the bit Im looking for in your code is this bit

Code:
$this->uri->segment(3)

if I call that within my controller I can then get the string out of the URL and then search the database for that string. Is that right?

so Id have something like this:

Code:
$job_title = $this->uri->segment(3);

    public function get_job_info($job_title)
    {
        $query = $this->db->query("SELECT * jobs WHERE title = $job_title");

  foreach ($query->result() as $row)
  {
     echo $row->title;
     echo $row->salary;
                   echo $row->info;
    
  }
    }

Thanks
#4

[eluser]CroNiX[/eluser]
Yes, except you'd want to db::escape() $job_title before using it in your query, or use Active Record which will escape it automatically. Never accept user input (which you are if you're using things from the url) without sanitizing/escaping, especially when being used in a database query.

You also might want to check and make sure uri:Confusedegment(3) is not FALSE before you run your query, which it will be if segment 3 doesn't exist.
#5

[eluser]boltsabre[/eluser]
Just a couple of things, if you are creating/calling

Code:
public function get_job_info($job_title){..

In your controller, you may want to consider moving it into a model (technically all DB related stuff should be in your model to adhere to the MVC structure). That way if you ever need to call the function from a different controller you don't have to "copy and paste" your function (keeps things DRY and reduces the chances of bugs and keeps your files smaller and more readable).

If you are always sure it will be uri segment 3 then there is no need to assign it to a variable, inside your function you can just do:
Code:
$query = $this->db->query("SELECT * jobs WHERE title = $this->uri->segment(3)");
This just saves on creating one extra variable that has to be committed to server memory (and make sure you escape it like CronNix said, active records would be best for a simple SELECT like this).

Or if the uri segment changes you could just do it like this:
Code:
// lets say this is your controller and you are calling a model method, and that your model is already loaded
// by just passing your uri number in the function call you don't have to assign it to a variable
$job_title = $this->jobs_model->job_title_by_uri(3);

//And lets say this was your model function
public function job_title_by_uri($uri_seg_numb){
   if($this->uri->segment($uri_seg_numb)){
      //this is checking if the uri segment actually exists
      // you may need to use isset(), or if($this->uri->segment($uri_seg_numb) != null) or something else,
      // I'm at work and cannot check on my CI installation and have forgotten, sorry!

      //but anyway, in here goes your code, again escape it using active records
      $query = $this->db->query("SELECT * jobs WHERE title = $this->uri->segment($uri_seg_numb)"
      
      //check if a result was returned, if it was return that, else return false.
   }else{
      //uri segment doesn't exist, return false
      return false;
   }
}

Also, only SELECT * (select all) if you absolutely have to. If you only need a one column from your table, just select that, again this reduces server memory requirements and will increase the speed of your queries.




Theme © iAndrew 2016 - Forum software by © MyBB