I am trying to configure pretty URLs in codeigniter and it's not making much sense to me. I'd like my URLs to follow the following structure;
example.com/admin/view/form/123
I can successfully view data when I visit the URL above. I see the same data when I visit;
example.com/admin/view/123
Notice the 3rd segment /form/ is missing, but still returns the data. It's almost like it's ignoring this - I thought CI should throw a 404 error, or do I need to check for this manually? If so, how?
When I visit this URL;
example.com/admin/view
I see the following error;
An uncaught Exception was encountered
Type: ArgumentCountError
Message: Too few arguments to function Admin::view(), 0 passed
My code can be seen below;
Controller
defined('BASEPATH') OR exit('No direct script access allowed');
class Admin extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->load->helper('url');
$this->load->database();
$this->load->model('Admin_model');
}
public function index()
{
$this->load->view('template/header');
$data = array(
'title' => 'Admin Page'
);
$this->load->view('admin/index', $data);
$this->load->view('template/footer');
}
public function view($form_submission_id)
{
$this->load->view('template/header');
$data = array(
'title' => 'Form View Page',
'record' => $this->Admin_model->getSubmissionById($form_submission_id)
);
$this->load->view('admin/view/index', $data);
$this->load->view('template/footer');
}
}
Model
class Admin_model extends CI_Model {
public function getSubmissionById($form_submission_id) {
$this->db->select('*');
$this->db->from('submissions');
$this->db->where('id', $form_submission_id);
$query = $this->db->get();
return $query->row();
}
}
Routes
// redirect any urls that contain a number after /form
$route['admin/view/form/(:num)'] = "admin/view/$1";
My views folder structure looks like this;
- views
-- admin
- index.php
- view
-- index.php
Ideally I want my URLs to look like this, and throw 404 errors where they don't.
example.com/admin/view/form/123
example.com/admin/update/form/123
example.com/admin/delete/form/123
You can do this by several ways.
The fastest way is by creating routes like this:
$route['admin/view/form/(:num)'] = "Admin/view/$1";
When typing exemple.com/admin/view/form/9 , it will redirect to the controller admin, function view and the "9" will be the parameter $form_submission_id
The same thing for routes below.
$route['admin/update/form/(:num)'] = "Admin/update/$1";
$route['admin/delete/form/(:num)'] = "Admin/delete/$1";
of course you could create a function for each one, view, update, delete ... etc
It's normal that you see error when you enter example.com/admin/view because the view function take 1 parameter $form_submission_id
Related
I'm developing a web application and i'm slightly confused by routes and how they work.
My web application has an admin area and the URL structure is as follows;
example.com/admin/view/form/123
My Admin controller looks like this;
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Admin extends CI_Controller {
public function index()
{
$data = array(
'title' => 'Admin Page'
);
$this->load->view('admin/index', $data);
}
public function view() {
$form_submission_id = $this->uri->segment(4);
$records = $this->Admin_model->getDetails($form_submission_id);
$data = array(
'title' => 'Form Details',
'records' => $records
);
$this->load->view('admin/view/index', $data);
}
}
I don't have any custom routes setup.
When I visit the following URL, I can see the page and corresponding data successfully;
example.com/admin/view/form/123
But, when I change the /form/ URL segment to something random like below I can still see the correct data;
example.com/admin/view/foo/123
Why is this?
I was expecting to see a 404 page?
What do I need to change in order to achieve what I want?
Perhaps i'm misunderstanding the logic and should have my controllers / routes setup differently?
Codeigiter URL has a structure as domain/controllerName/actionName/param1/param2 and so on. In your code URL example.com/admin/view/form/123 admin is controller, view is action name and form and 123 is the parameters which you passed using get method. You can access these parameters like $this->uri->segment(3).
Thus in your code:
It will not show any error as your function is not even using 3rd URI segment.
It will not show 404 page as it found correct controller and action.
To achieve domain related functionality, you need to either change for function code accordingly or need to use routes for this.
Hope it helps you to clarify this code.
Rohit Mittal answer is good and also,
You can change the view fuction in admin controller like as:
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Admin extends CI_Controller {
public function view($form = null,$form_submission_id = null) {
if($form == "form" && $form_submission_id){
$records = $this->Admin_model->getDetails($form_submission_id);
$data = array(
'title' => 'Form Details',
'records' => $records
);
$this->load->view('admin/view/index', $data);
}
}
I have a custom 404 controller. It works fine. In routes.php I have:
$route['404_override'] = 'custom404';
this accesses this controller:
class custom404 extends MasterController {
public function __construct(){
parent::__construct();
}
public function index(){
$this->output->set_status_header('404');
$crit = array(
'subtype' => 'footer',
'status' => 'public'
);
$res = $this->mongo_db->where($crit)->get('contentobjects');
$this->pagedata = $res[0];
$this->load->view('404');
}
}
Can I call this from a different controller?
Currently I'm just forcing the issue by calling an (ostensibly) never-extant page:
if(!$this->viewable($res[0])){
header('Location: /404');
die;
}
Yes you can, just redirect to it directly.
However CI comes with an errors folder, with a sub folder for HTML and a 404 error view page. If you customize this page all your headers will be set correctly automatically, and you can call it in a much clearer manner.
if (empty($result))
{
// show error
show_error('The result you requested could not be found', '404');
}
Or more concisely:
if (empty($result)) show_error('The result you requested could not be found', '404');
The message here can be accessed in the template with $message field.
You can then easily set any code you need, like 401 etc.
http://www.codeigniter.com/user_guide/general/errors.html
I am trying to send a url from view page to controller but it does not seem to work the way i am thinking.
View Page
Product
User
I want to get "tbl_product"
Controller admin
<?php
class Admin extends CI_Controller {
public function test() {
echo $this->uri->segment(4);
}
}
?>
but if the segment(4) is changed to segment(3), it shows up with displaying "product" in the screen
your controller function should have arguments for your url segments
for example:
public function test($product = 'product', $tbl = 'tbl_product') {
echo $tbl // contains the string tbl_product
}
Since you said your routes look like this:
$route['default_controller'] = "admin";
$route['404_override'] = ''
and your URL is like this:
<?= base_url() ?>admin/test/product/tbl_product
Then if your base_url() is localhost/my_app, your URL will be read as this:
http://localhost/my_app/admin/test/product/tbl_product
http://localhost/my_app/CONTROLLER/METHOD/PARAMETER/PARAMETER
So in your controller, you can do this:
class Admin extends CI_Controller {
public function test($product = NULL, $tbl_product = NULL) {
echo $product;
echo $tbl_product;
}
}
It's strange to use codeigniter for this purpose, because codeigniter uses as default the url format bellow.
"[base_url]/[controller]/[method]"
I think it will be better and more easy to just pass the values you want as get parameters and make some httaccess rules to make your url more readable for the user and robots. That said you can do that:
Product
<?php
class Admin extends CI_Controller {
public function test() {
echo $this->input->get('product');
//should output 'tbl_product'
}
}
?>
If you prefer to use uri instead u should route your uri's so it will be like.
In your routes file you probably I'll need something like this.
$route['product/(:any)'] = "Admin/test";
This way you will probably access the uri segments correctly.
Thank you so much for going through.
$this->uri->segment(4); // is now working :S
its not working properly after all I made changes to routes.php and came back to default again. I seriously have no idea what the reason behind not displaying the result before.
i am currently learning CI and i have come to an issue that i cant seem to solve.
i set up my wamp server in a drive and inside the www(root) folder i have extracted the codeigniter files.
![example][1][1]: http://i.stack.imgur.com/7RKqG.png
then I created my php files for view/model and controller and set the default route in the config/routes.php
so now when I go to my browser and type localhost I get the post.php displayed without anyissue.
but I am unable to access any of the views from here. for example i have a new_post.php view and when i type in the address bar localhost/new_post.php i get a "Not Found
The requested URL /new_post.php was not found on this server." error.
what am i doing wrong? below i have posted the code which i have written in the post.php controller along with a image of the file structure/names i have.
posts.php - controller
<?php
class Posts extends CI_Controller
{
function __construct()
{
parent::__construct();
$this->load->model('post'); //loads the post model u created in the models folder
}
function index() //goes to this function 1st when u access the controller
{
$data['posts']=$this->post->get_posts(); // load all the data from the get_posts function in post model to the data array posts
$this->load->view('post_index', $data); //loads the view
}
function post($postID)
{
$data['post']=$this->post->get_post($postID);
$this->load->view('post', $data);
}
function new_post()
{
if($_POST)
{
$data=array(
'title'=> $_POST['title'],
'post'=> $_POST['post'],
'active' =>1
);
$this->post->insert_post($data);
redirect(base_url(). 'posts/');
}
else
{
$this->load->view('new_post');
}
}
function editpost($postID)
{
$data['success']=0;
if($_POST)
{
$data_post=array(
'title'=> $_POST['title'],
'post'=> $_POST['post'],
'active' => 1
);
$this->post->update_post($postID,$data);
$data['success'] =1;
}
$data['post']=$this->post->get_post($postID);
$this->load->view('edit_post',$data);
}
function deletepost($postID)
{
$this->post->delete_post($postID);
redirect(base_url(). 'posts/');
}
}
![structure][1] [1]: http://i.stack.imgur.com/SnsbW.png
In CodeIgniter you have to use controller to get access to his function
you are saying "when i type in the address bar localhost/new_post.php i get a Not Found" because you try to direct access its function name you have to use example.com/controllername/functionname like this
http://localhost/posts/new_post
for more information check codeignier url
https://ellislab.com/codeigniter/user-guide/general/urls.html
if you not removed index.php using .htaccess then you have to use your url like this
http://localhost/index.php/posts/new_post
In CodeIgniter, everything runs through the main "index.php" file, in your root directory.
So, you would access your new post page, like this;
http://localhost/index.php/posts/new_post
Have a read through the CodeIgniter user guide, it will answer any problem you have.
https://ellislab.com/codeigniter/user-guide/
I have a login script, and when the login is successful I want it to redirect them to the home page(welcome_message.php) for some reason it does not link me to this file, instead throws a 404 and says "The requested URL "http://localhost/musiclear/index.php/views/welcome_message" cannot be found or is not available. Please check the spelling or try again later."
I am using CodeIgniters redirect() function for the change.
function validate_credentials() {
$this->load->model('membership_model');
$query = $this->membership_model->validate();
if ($query) { // if users credentials validated
$data = array('usernames' => $this->input->post('username'),
'is_logged_in' => true);
$this->session->set_userdata($data); //set session data
redirect('welcome_message'); //redirect to home page
} else { //incorrect username or password
$this->index();
}
}
Try passing the full URI to the redirect function like so:
redirect(base_url('views/welcome_message'));
Assuming of course that your controller is Views and page (function) is welcome_message
You can't redirect browser to view file directly, but You can redirect it to controller, which will show Your view. In Your example You're trying to access CodeIgniter's (which based in musiclear folder on Your localhost) Controller with name views and call welcome_message() method from it. But if Your really want to show it You must have next structure:
musiclear/
Application
Controllers
views.php
and views.php content:
<?php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class Views extends CI_Controller {
function index() {
// default action, required method
}
function welcome_message(){
$this->load->view('welcome_message');
}
}
?>
actually when you make redirects in CodeIgniters it looks up for your controller and you should load view through the function of controller. e.g:
function validate_credentials() {
$this->load->model('membership_model');
$query = $this->membership_model->validate();
if ($query) { // if users credentials validated
$data = array('usernames' => $this->input->post('username'),
'is_logged_in' => true);
$this->session->set_userdata($data); //set session data
redirect(base_url().'home/welcome'); //redirect to home function
} else { //incorrect username or password
$this->index();
}
}
function welcome(){
$this->load->view('welcome_mesage');
}
May be you forgot that redirect() function work only for controller class ie.
let you have welcomeclass so you can redirect it by using
redirect('wolcome');
you also redirect a function of controller class
if you want to redirect to page function of welcome controller class so you will writr
redirect('welcome/page');