PHP, CodeIgniter y jQuery
CodeIgniter: Aplicación Básica (I), Creación de un Blog
Después de la introducción de como configurar CodeIgniter, lo mejor sería empezar con un ejemplo básico de como usar CodeIgniter. Lo más común son los sistemas de noticias o un weblog, que funcionarían igual (añadir a una base de datos, listar juntos, listar individuales), así que vamos a crear uno.
Lo primero que vamos a necesitar es CodeIgniter, podéis recurrir a la web oficial para descargarlo o usar la pre-configuración del artículo CodeIgniter: Iniciación y Configuración (concretamente este). Una vez descomprimido vamos a renombrar algunos ficheros y configurar algunos.
Accedemos a /application/controllers/ y cambiamos el nombre de welcome.php a blog.php. Blog.php será la base de nuestra aplicación, el controlador principal. Lo abrimos y veremos como es, por defecto, un controlador de CodeIgniter. En este primer ejemplo no vamos a usar modelos para no complicar las cosas, en un futuro, lo haremos. Editamos nuestro archivo blog.php para que quede tal que así:
Archivo: /application/controllers/blog.php
[code lang="php"]
class Blog extends Controller {
function Blog()
{
parent::Controller();
}
function index()
{
}
}
?>
[/code]
Es sumamente importante que sea class Blog y no class blog, al igual que function Blog() y no function blog().
Ahora vamos a configurar CodeIgniter para que su controlador principal sea blog.php de modo que cuando accedamos a la pagina web sin establecer controlador alguno, sea blog.php el controlador por defecto. Para hacer esto necesitamos configurar el archivo routes.php y podemos encontrarlo en /application/config. Routes.php se ocupa de las rutas de nuestra URI, se usa habitualmente para redirigir cosas a los controladores. Si por ejemplo queremos que una dirección tipo /producto/id/123 vaya a productos.php y /producto/nombre/abc también vaya a productos.php podríamos usar algo similar a esto:
[code lang="php"]
$route['/producto/id/:num'] = "productos/productById";
$route['/producto/name/:any'] = "productos/productByName";
[/code]
Siendo productById y productByName dos funciones dentro del controlador productos.php. Bien, pero eso no es lo que necesitamos nosotros ahora mismo. El archivo routes.php también se usa para establecer el controlador por defecto y por defecto hay el welcome, nosotros lo cambiaremos por blog:
Archivo: /application/config/routes.php, Línea: 43
[code lang="php"]
$route['default_controller'] = "blog";
[/code]
También será necesario usar autoload.php, también en /application/config/ para cargar automáticamente una librería (database) y un helper (url):
Archivo: /application/config/autoload.php, Línea: 42
[code lang="php"]
$autoload['libraries'] = array("database");
[/code]
Archivo: /application/config/autoload.php, Línea: 54
[code lang="php"]
$autoload['helper'] = array("url");
[/code]
Al añadir database al array de librerías, se cargar cada vez que accedamos a cualquier controlador. Como nuestra aplicación estará basada en la base de datos, y la usaremos todo el rato, ya nos va bien cargarla al principio. El helper url lo vamos a usar para
Base de Datos
Ahora realmente empezamos a trabajar con la aplicación, lo primero que necesitaremos será una base de datos MySQL. Para configurar los datos de la base de datos deberemos acceder a /application/config/database.php como ya expliqué en el artículo CodeIgniter: Iniciación y Configuración. Una vez configurado, crearemos nuestra tabla. El esquema sería el siguiente:
[code]
CREATE TABLE `posts` (
`id` int(5) NOT NULL auto_increment,
`title` varchar(64) NOT NULL,
`url_title` varchar(64) NOT NULL,
`body` text NOT NULL,
`created_on` varchar(10) default NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
[/code]
El único campo que puede confundir un poco es el campo url_title, este campo lo usaremos para crear URI tipo: blog.iplauas.es/este-seria-el-url-title.
Controlador y vistas
Vamos a crear nuestro controlador. Los controladores los podemos dividir mediante funciones, nosotros vamos a usar la función index() para mostrar las entradas, show() para ver una entrada en particular (enlace permanente) y add() para añadirlas.
Lo primero que haremos en nuestra función index() va a ser la consulta a MySQL. En esta consulta, pondremos en un array() todas las entradas que tengamos en nuestra tabla MySQL. Debería ser algo así:
Archivo: /application/controllers/blog.php
[code lang="php"]
function index()
{
$query = $this->db->orderby("id","desc");
$query = $this->db->get("posts");
foreach ($query->result() as $row) {
$data["posts"][$row->id]["title"] = $row->title;
$data["posts"][$row->id]["url"] = $row->url_title;
$data["posts"][$row->id]["body"] = $row->body;
$data["posts"][$row->id]["date"] = $row->created_on
}
}
[/code]
Como podéis comprobar, lo primero que hacemos es ordenarlos por ID y luego almacenamos en el array $data["posts"] el contenido de las entradas. Sin embargo, tengo planteado guardar la fecha en timestamp de modo que necesitaremos convertirla a una fecha humana. Para esto usaremos el helper date de CodeIgniter. Para cargar un helper debemos usar la expresión: $this->load->helper();. En nuestro caso, crearemos un patrón para las fechas que lo almacenaremos en una variable:
Archivo: /application/controllers/blog.php
[code lang="php"]
function index()
{
$query = $this->db->orderby("id","desc");
$query = $this->db->get("posts");
foreach ($query->result() as $row) {
$data["posts"][$row->id]["title"] = $row->title;
$data["posts"][$row->id]["url"] = $row->url_title;
$data["posts"][$row->id]["body"] = $row->body;
$data["posts"][$row->id]["date"] = $row->created_on
}
}
[/code]
De este modo la fecha se mostrará DD-MM-AAAA. Con esto tenemos nuestro controlador index() listo. Solo nos falta añadir la salida, lo que llamaremos view y podemos encontrar en /application/views/. Si accedemos al directorio veremos el archivo welcome_message.php, le cambiaremos el nombre a blog_front.php. Lo abrimos con nuestro editor de textos y veremos que hay establecidos unos estilos (CSS), vamos a usar los mismos.
Lo primero que necesitamos saber es como cargar la vista desde nuestro controlador, para cargar la vista lo haremos con $this->load->view();. Otro tema de las vistas es añadirle nuestro contenido dinámico, para pasar el contenido tendremos que añadir una variable. Veamos como lo haríamos en nuestro ejemplo, siendo nuestro contenido el array $data.
Archivo: /application/controllers/blog.php
[code lang="php"]
function index()
{
$query = $this->db->orderby("id","desc");
$query = $this->db->get("posts");
$this->load->helper('date');
$datestring = "%d-%m-%Y";
foreach ($query->result() as $row) {
$data["posts"][$row->id]["title"] = $row->title;
$data["posts"][$row->id]["url"] = $row->url_title;
$data["posts"][$row->id]["body"] = $row->body;
$data["posts"][$row->id]["date"] = date($datestring,$row->created_on);
}
$this->load->view("blog_front",$data);
}
[/code]
Si ejecutáis este código, funcionará al 100%. Sin embargo, en nuestra vista, no vamos a ver más que el mensaje estático del welcome_message.php que hemos renombrado. Ahora es el momento de empezar a crear como se verá. Vamos a hacerlo muy sencillo para que veáis como trabajar con las variables que hemos pasado. Entre las dos etiquetas body del archivo blog_front.php, vamos a poner este código:
[code lang="php"]
foreach ($posts as $id => $post) {
echo "
".anchor($post["url"],"#".$id)." ".$post["title"]."
";
echo "
".$post["body"]."
";
echo "".anchor($post["url"],"Enlace Permanente")." - ".$post["date"]."";
}
?>
Pagina generada en {elapsed_time} segundos
[/code]
Como podéis recordar, nosotros teníamos una variable $data["posts"], que realmente es un array $posts dentro del array $data. Dentro del array $posts tenemos un array para cada ID de entrada. Para eso usamos la función foreach, para “dividir” estos arrays y generar el contenido para cada ID. En cuanto al contenido dentro del ID podéis fijaros en la siguiente expresión:
[code lang="php"]
anchor($post["url"],"#".$id)
[/code]
anchor() es una función que forma parte del helper url que hemos usado en autoload.php. En el primer termino de la función especificamos la dirección a donde debe apuntar el enlace y, en la segunda, el texto a mostrar.
Con esto que tenemos ya podemos mostrar las entradas correctamente, ahora vamos a crear la función show() en blog.php para ver una específica. Para empezar, clonaremos el blog_front.php y lo nombraremos blog_single.php. De momento lo dejaremos así. Volveremos al controlador blog.php y añadiremos el siguiente código:
[code lang="php"]
function show()
{
$url_title = $this->uri->segment(1, 0);
if($url_title) {
$this->load->helper('date');
$datestring = "%d-%m-%Y";
$query = $this->db->where("url_title",$url_title);
$query = $this->db->get('posts');
foreach ($query->result() as $row) {
$data["post"]["id"] = $row->id;
$data["post"]["title"] = $row->title;
$data["post"]["url"] = $row->url_title;
$data["post"]["body"] = $row->body;
$data["post"]["date"] = mdate($datestring,$row->created_on);
}
$this->load->view('blog_single',$data);
} else {
redirect();
}
}
[/code]
Podemos ver que el código es prácticamente igual al de la función index(), pero este tiene una particularidad: muestra solo una entrada. Como podéis ver, al principio del código establecemos el $url_title con $this->uri->segment(1, 0);. Esto nos permite recibir un segmento determinado de la URI, en nuestro caso, el primero. Acto seguido comprobamos si existe algo establecido y si existe empezamos a montar la estructura. Hemos añadido una cosa en la sentencia $query, hemos usado $this->db->where(“url_title”,$url_title); para establecer que el campo url_title de la base de datos sea igual al $url_title.
Si todo esto no se cumpliera, hay un redirect() que los envía al principio de la aplicación.
También tenemos que cambiar el código de nuestra vista, ya que solo hemos duplicado el archivo. Entre las etiquetas
y debería haber algo así:Archivo: /application/views/blog_single.php
[code lang="php"]
=anchor($post["url"],"#".$post["id"]);?> =$post["title"];?>
=$post["body"];?>
=anchor($post["url"],"Enlace Permanente");?> - =$post["date"];?>
Page rendered in {elapsed_time} seconds
[/code]
Solo nos falta un truco que hemos usado en archivo routes.php que hemos hablado antes:
Archivo: /application/config/routes.php, Línea: 46-49
[code lang="php"]
$route["blog"] = "blog";
$route["add"] = "blog/add";
$route[":any"] = "blog/show";
[/code]
Añadir entradas
Esta es la última parte de nuestra aplicación básica, como añadir una entrada a la base de datos. Es muy sencillo. Para empezar esta vez crearemos primero la vista. Copiamos uno de las vistas y cambiamos el nombre por blog_add.php. Vamos a usar otra de helpers de CodeIgniter para crear el campo de formulario, form. Entre las etiquetas
y debería quedar algo tal que así:Archivo: /application/view/blog_add.php
[code lang="php"]
Añadir entrada
=form_open("add");?>
=form_close();?>
=$this->validation->error_string; ?>
Page rendered in {elapsed_time} seconds
[/code]
Lo único que os puede despistar aquí es el $this->validation->error_string;, forma parte de una de las librerías de CodeIgniter que vamos a usar en nuestro controlador para validar los campos. Se usa para que, si al validar el formulario hay un error, mostrar en el mismo archivo el error. Para poder añadir la entrada a nuestro controlador blog.php vamos a añadirle el siguiente código:
[code lang="php"]
function add()
{
$this->load->library("validation");
$this->load->helper("form");
$admin_password = "prueba";
$rules["title"] = "trim|required|min_length[3]|max_length[64]";
$rules["body"] = "trim|required|min_lenght[50]";
$rules["password"] = "trim|required";
$this->validation->set_rules($rules);
$fields["title"] = "título";
$fields["body"] = "contenido";
$fields["password"] = "contraseña";
$this->validation->set_fields($fields);
if ($this->validation->run() && $this->input->post("password") == $admin_password) {
$this->load->helper("date");
$insert = array(
"title" => $this->input->post("title"),
"url_title" => url_title($this->input->post("title")),
"body" => $this->input->post("body"),
"created_on" => now()
);
$this->db->insert("posts", $insert);
redirect("");
}
$this->load->view("blog_add");
}
[/code]
Como podéis ver, al principio del código, lo primero que hacemos es cargar la librería validation que hemos comentado antes. También cargamos el helper form para crear el formulario. El sistema de “protección” es algo cutre, pero no era la misión de este artículo precisamente. Hemos establecido una contraseña que se validará cuando enviemos la entrada. Seguidamente establecemos, gracias a la librería validation, que es lo que los campos deben cumplir. Acto seguido, por si algo falla, establecemos unos nombres “humanos” a los campos.
Si todo lo anterior valida, y la contraseña que hemos puesto en el formulario es igual a la establecida en el campo $admin_password, podremos montar el array $insert que luego usaremos para añadir el contenido a la base de datos. Como podéis ver en el campo “url_title” usamos la función url_title() para crear unos vínculos más accesibles y no un simple id. Una vez hemos añadido el contenido redirigimos a la pagina principal. Si esto falla volvemos a cargar la vista blog_add.php.
Conclusión
Con todo esto ya podéis crear vuestra primera aplicación en CodeIgniter usando bases de datos, varias vistas y usando routes.php para redirigir las URI. Es una base bastante fuerte para empezar a desarrollar algo encima. Próximamente enseñaré como hacer un sistema de usuarios bastante para evitar que la gente vea nuestra administración.
Descargar el ejemplo “Aplicación Básica (I), Creación de un Blog”: ipalaus-CodeIgniter_BlogExample_v1.rar
| Imprimir artículo | Este artículo fue publicado por Isern Palaus el 11 Marzo 2008 a las 12:35, y está archivado en CodeIgniter. Sigue las respuestas a esta entrada a través de RSS 2.0. Puedes dejar un comentario o enviar un trackback desde tu propio sitio. |
hace 2 años
Interesante y muy útil pero ¿como deberían formarse las urls para utilizar los métodos del controlador blog?Es decir, sin utilizar el archivo routes.php
intente crear los enlaces pero al tratarse de métodos simplemente me perdí
Primero (antes desactive la línea en routes) intente escribir blog/add pero la ruta esta fijada para que inicie en la aplicación blog, borre la palabra blog y tampoco.
Por cierto solo le faltaría al código validar si tiene resultados para que no genere advertencias, en el método add cuando intento guardar me sale un error.
Saludos.
hace 2 años
Disculpa se me paso poner el error:An Error Was Encountered
Error Number: 1366
Incorrect string value: ‘\xF1adir …’ for column ‘body’ at row 1
INSERT INTO `posts` (`title`, `url_title`, `body`, `created_on`) VALUES (‘Ejemplo desde form’, ‘ejemplo-desde-form’, ‘Esta entrada es desde la forma de añadir entrada’, 1207609583)
Supongo que el error se genera al intentar convertir o enviar la letra Ñ :S
hace 2 años
Hola Alberto,Respondiendo a la primera pregunta de tu comentario, a los controladores se accedería con: index.php/CONTROLADOR/FUNCIÓN por lo que index.php/blog/add debería funcionar.
¿A que te refieres en validar si tiene resultados?
En cuanto al error, he estado buscando en la super User Guide de CodeIgniter y creo que deberías probar de usar el helper “text”. Yo ahora mismo no puedo probarlo pero bueno, así aprovechas y practicas un poco
.
¿Como deberías hacerlo? Muy sencillo, el helper tiene una función llamada asii_to_entities(); que si no me equivoco es justamente para corregir estos errores. Entonces, en la función add(), después de cargar el helper form carga el text. Entonces, en el array para insertar datos, fíjate en:
Deberías añadir la función ahí mismo, de modo que $this->input->post(“body”) quedaría ascii_to_entities($this->input->post(“body”)).
Si no te aclaras, aquí tienes la información de Text Helper.
Un saludo y espero haberte ayudado,
– Isern Palaus
hace 2 años
Desactive las entradas en el archivo routes.php y modifique el vínculo a la función ADD, además de agregar el controlador a la instrucción del form echo form_open(“blog/add”) hasta ahí todo bien.Seguí tu recomendación y utilice ascii_to_entities($string), con el texto:
“Uso de acentos. La canción causaba la alegría de los niños.”
pero solo obtenía:
“Uso de acentos. La cancin causaba la alegr᳭a de los nios.”
Lo que me desconcierta ya que convirtió solo la letra “í” y eliminando el resto de caracteres (ó y ñ).
Después de cambiar la codificación en el archivo de configuración, que de paso nunca supe si la tomo
probe sin buenos resultados, agregue la codificación en la vista con las etiquetas html correspondientes y tampoco obtuve resultados.
Haciendo una búsqueda en el foro me encontré con este mensaje (último comentario):
http://codeigniter.com/forums/viewthread/73660/
donde explican que solo basta cambiar la codificación en la BD (mysql en mi caso)
$db[’default’][’char_set’] = “latin1″;
$db[’default’][’dbcollat’] = “latin1_swedish_ci”;
Lo anterior en mi caso funciono, pero considero que depende del conjunto de caracteres con el cual se instaló la BD.
Un comentario antes se propone el uso de utf8_encode($string) y utf8_decode($string) (convierte a UTF8 desde ISO 8859-1 y el proceso inverso) pero como dije en el paso anterior al solucionar mi problema ya no lo probé.
También proponen otras soluciones como la del último comentario en este otro mensaje:
http://codeigniter.com/forums/viewthread/73379/
En cuanto al show logre hacerlo trabajar con pequeños cambios y gracias a la misma recomendación que mencionaste con la función ADD.
Solo hay algo que no termino de entender y es esta línea:
$url_title = $this->uri->segment(1, 0);
En mi caso la convertí en un comentario ya que la función show recibe la url como parámetro.
Ya para terminar que el mensaje esta quedando un poco largo. Cuando te mencione validar si tiene resultados, me refiero a que una vez realizada la consulta se compruebe que en realidad existen registros o en su defecto declarar el arreglo $data antes.
Porque si no hay resultado nunca entra al foreach (¿o si?). Ya que al principio cuando la BD estaba vacía me generaba error la vista blog_front donde me informaba que la variable “posts” no existía, la cual es enviada desde el controlador blog.
En esta última parte si tengo una idea errónea te agradeceré mucho me puedas esclarecer el tema.
De antemano gracias.
Saludos.
P.D. Ya te agregue en el blog
hace 2 años
Hola Alberto,Perfecto, lo del routes.php solo deberías fijarte en a lo que esta igualada la variable y eso deberías substituir.
En cuanto el ascii_to_entities(); entonces veo que fue un error recomendarlo, ya lo se para una próxima. La verdad es que había buscado en el foro de CodeIgniter sobre el error que me comentabas. De hecho lo había experimentado, por lo que es posible que hayas visto mi post ahí. Había visto que hablaban de la codificación pero al ver que tabla usaba el charset latin1 no caí en ello. Un muy buen apunte.
A lo que comentas que es posible que sea la base de datos, si le pones el charset en la base de datos no hará falta usarlo en la configuración de database.php. De todos modos esta usando el swedish, creo que el spanish también existe
.
El uso de utf8_encode() y utf8_decode() quizá seria lo que deberíamos usar en nuestros proyectos, pues es el estándar. Pero si funciona de la otra manera, ahora no creo que sea muy necesario modificar tu código de nuevo
. Se usaría de la misma manera que te comenté antes lo del ascii_to_entities() en el mismo sitio, y a la hora de llenar el array con los datos pues igual pero con el utf8_decode().
En cuanto a:
http://codeigniter.com/forums/viewthread/73379/
Se refiere a la URI, la URI es la dirección, la URL vaya… No creo que eso solucionara nada.
La variable $url_title = $this->uri->segment(1, 0); la uso para determinar dónde esta el nombre de la entrada. Es decir, si te fijas la dirección de la entrada de este blog es:
http://blog.ipalaus.es/codeigniter-aplicacion-basica-i-creacion-de-un-blog
Por lo que, usando $this->uri->segment(1,0); obtendríamos codeigniter-aplicacion-basica-i-creacion-de-un-blog. Una vez tengo $url_title lo uso para buscar en la base de datos que entrada coincide con esta por tal de mostrar el contenido.
Por otra parte, tienes razón el lo de comprobar antes el array $data para empezar con los echo. El script lo hice rápidamente y muchas cosas me las salté… Por ejemplo, la administración… Es bastante decepcionante el sistema, pero te prometo que este fin de semana publico mi sistema de usuarios
!!
Muchas gracias por tus comentarios.
Un saludo,
– Isern Palaus
hace 2 años
Je, je.. bueno la crítica fue constructiva entiendo eso de generar ejemplos rápido (lo habrás visto en el post en el que comentaste XDD)Yo lo comentó más que nada por las personas que están iniciando y pueden perder horas con algo que no es un error como tal
Gracias de nuevo por la explicación de la instrucción y el enlace en el foro. Entiendo que en mi caso al pasar el title al método show no requiero esa instrucción.
Estaré esperando ese sistema de usuarios
por cierto haz combinado la librería ExtJS con CI. Tengo muy poco de haber iniciado el uso de ambos pero con ExtJS me he ahorrado mucho tiempo de desarrollo.
Saludos.
hace 2 años
muy bueno el post :d muchas gracias por la explicacion voy a seguir viendo los otros post pa entender mejorhace 1 año
hola tengo una duda:cuando yo creo un form en mi vista, y le pongo la accion a un controlador usuarios.php, si este no es mi usuario requerido,
?con que puedo redireccionar hacia la misma pagina, enviando datos de error?
?por que usando $this->load->view lo cargado no tiene css, si anteriormente esta vista lo tenia?
Gracias amigos….
hace 1 año
Supuestamente, al crear un ‘anchor()’ y darle enlace a un controlador ya creado (por ejemplo ‘prueba’) tendría que funcionar automáticamente, no?Lo digo por que tengo un enlace a otro controlador con anchor(‘prueba/’, ‘Cliquee aquí’); y no me carga ese controlador, qué puede ser? También tengo el $route['prueba'] = ‘prueba’; y nada de nada.
Una ayudita?
hace 1 año
hola, como puedo hacer enlaces en code igniter, no puedo lograr que se me cargue la pagina de una a otra :Shace 9 meses
hola estoy manejando UTF8 y utiliso utf8_decode para reconocer la ñ pero me aparece es un signo de interrogacio ?, como hago para que me reconosca la ñ si tengo en una variable la cadena pero no me la reconoce hago lo siguienteif($cadena[$i]>=’a’ && $cadena[$i]<='z'||$cadena[$i]=='ñ') pero me reconoce la ñ como ?
hace 6 meses
Hola estoy probando el código del blog y me tira el siguiente error:A PHP Error was encountered
Severity: Notice
Message: Undefined variable: data
Filename: controllers/blog.php
Line Number: 45
Cuando intento acceder a las funciones show y add. Recien me estoy iniciando en CodeIgniter y no se a que se debe el error.
Espero me puedas ayudar a resolverlo.
gracias!!