• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

Knitter

Problema no uso do CodeIgniter

19 mensagens neste tópico

Boas,

Estava para aqui a fazer uns testes com esta framework para ver o que dela conseguia obter quando me deparo com um erro, para mim, estranho. Isto porque não sou dos mais adeptos de PHP e posso estar a não perceber alguma coisa básica, mas ao mesmo tempo não me parece um erro de PHP mas sim do meu uso da framework.

Passando a explicar, estou a fazer um teste bastante simples em que instalei a framework da forma tradicional, e estava a tentar criar um controlador genérico que, dependendo do link que o utilizador usasse, criasse os dados a mostrar e os enviasse para a vista.

Neste caso a vista é sempre igual, só muda mesmo o conteúdo.

Supostamente, pelo que vejo na documentação, para passar dados para a vista não é necessário mais que passar um array na chamada da vista, ora isso, no meu caso, funciona se o utilizador passar pela função index, mas se passar por qualquer outra das funções não funciona.

O meu controlador genérico tem o seguinte código

<?php
class Director extends Controller {

    function index() {
        $this->home();
    }

    function home() {
        $data['title'] = 'DevTe@m';
        $data['h1'] = 'home';
        $this->load->view('template', $data);
    }

    function contacts() {
    }

    function projects() {
    }

    function support() {
    }

    private function generic($data) {
    }
}

?>

Da vista tenho este excerto

    <?php echo link_tag('/css.css') ?>
    <title><?php echo $title; ?></title>

Se o utilizador aceder a http://localhost/devteam, passando pela função index, tudo funciona, se passar pelo url http://localhost/devteam/index.php/home recebo o erro de que a variável $title, usada na vista, não está definida.

Ainda podia pensar que seria pelas chamadas de funções diferentes, mas o que estou a fazer é, na função index, delegar o comportamento para a função home.

Resumindo, o que é que se está a passar?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Partindo do principio que estás a usar o formato de urls que vem configurado por defeito, então tás a formar o teu url mal.

Deve ser

[base_url]/controlador/função

tu tens

[base_url]/função

O que chamará a função que estiver definida para ser chamada por defeito (se não mexeste em nenhuma ocnfiguração é a função index() ) no controlador com o nome 'função'

Mas o que é deveras esquisito é o erro que te dá, a não ser que tenhas um controlador chamado home.

Importante referir é que, se não gostares deste esquema de urls é perfeitamente possível usar outro.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Estava com alguma pressa para ir dormir e não escrevi como deve de ser.

O controlador por omissão chama-se 'director'. Os endereços http://localhost/devteam, http://localhost/devteam/index.php e http://localhost/devteam/index.php/director funcionavam como deviam, e a função 'index' era correctamente chamada.

O endereço http://localhost/devteam/index.php/director/home não funcionava.

Digo não funcionava, porque hoje liguei o apache e assim que fui aos ditos endereços já funciona, pelo que não faço ideia do que possa ter corrido mal.

Já agora, aproveito para perguntar, já que não encontrei muita documentação sobre isso, como fazer para criar links para outras páginas de forma correcta?

Também preciso de ver como criar uma aplicação em mais que uma língua e a documentação oficial é algo escassa nisso, aliás, acho a documentação demasiado escassa e parece feita para quem já tem experiência com o sistema....

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Há mais do que uma maneira, eu uso esta porque funciona sempre, tipo, podes mover a aplicação de sítio que os links continuam todos a funcionar sem problemas.

site_url("controller/function/bla/bla");

Para geração de links identicos mas com paramtros diferentes eu costumo criar funções protegidas, tipo isto:

	function _opensearch_url($hash){
	return  site_url("opensearch/$hash");
}

Em relação ao manual é que estou surpreendido com a tua opinião, para mim é uma das grandes mais valias do CI é o manual que acho bastante completo e facil de seguir.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

O manual é simples de seguir e fácil de entender e ler, não questiono isso, mas para mim que estava a começar falta qualquer coisa, por exemplo, no guia básico faria sentido uma das primeiras coisas ser a apresentação de como referenciar ficheiros CSS, imagens, criar links para outras páginas, etc. Isso não acontece.

Por exemplo, o erro que me estava a dar já sei o que é, se criar um array e o passar para dentro da função de load->view, como está na documentação, então tudo funciona bem, se quiser colocar uma função genérica pelo meio, parece que a variável já não é detectada como array ou acontece qualquer coisa que faz com que os elementos do array não sejam passados para variáveis na vista. Ora o processo de como isto tudo funciona não é explicado. O manual é muito tipo receita, "coloque isto aqui, aquilo ali e vai ver que tudo funciona", ora se eu perceber qual o objectivo vou mais facilmente saber o que quero fazer.

Neste caso queria criar um sistema que permitisse detectar a lingua do browser e que permitisse mostrar o conteúdo segundo essa detecção, mudar os links, etc. Pelo manual a ideia que me dá é que terei de fazer mais controladores do que o que queria, queria tudo no mesmo controlador, por exemplo, já que neste caso é tão simples que não faz sentido meter mais, não vejo no manual como fazer as coisas.

Os exemplos não dizem muitas vezes onde são colocados ou onde são executados, enfim, é simples de seguir mas sinto falta de muita coisa, para um exemplo simples e para começar tem lá tudo, mas eu não quero começar pelo simples, quero começar a usar a framework para a mesma complexidade que já fazia com outros sistemas.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Para internacionalização um controlador é capaz de não ser a melhor opção, a aproximação típica é o uso de dicionários de strings, pode ser usado por exemplo um array de arrays associativos.

A detecção da lingua deve ser feita no construtor dos controladores já que é para ser usada em praticamente tudo quanto é página.

O codeigniter permite-te chamar métodos de outros controlatores estaticamente. Eu tenho chamdas dessas em código meu, mas para ser franco quando as uso é em situações em que o desenho da aplicação está mal feito, nomeadamente a divisão entre controladores.

E acarreta muitas encrencas quando o faço pois muitas vezes as funções não estão feitas para ser chamadas estaticamente.

A forma mais espedita de fazer isso acredito que é usando um hook que é chamado em cada inicialização de classe.

É uma coisa que nunca usei mas que considero uma das features mais cool do codeignitor.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Para internacionalização um controlador é capaz de não ser a melhor opção, a aproximação típica é o uso de dicionários de strings, pode ser usado por exemplo um array de arrays associativos.

Eu não estou a usar, ou a pensar usar, um controlador para a internacionalização, estou a usar um controlador único para todas as páginas e uma vista única para todas as páginas, onde a única coisa que muda na vista é definida pelo controlador. E esta abordagem está a dar-me alguns problemas :)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Usando um controlador único então a internacionalização até se torna numa coisa mais simples.

O que eu fazia era guardar a língua num atributo, escrever uma pequena função para actualizar esse atributo e depois implementar uma função para sacar as strings na língua em questão.

Podes utilizar por exemplo helpers como language files.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Pause!

Primeiro, o meu problema com a língua ainda não está a ser considerado dado que será algo a introduzir depois. E esse até era o processo que estava a pensar :), apesar de ter de introduzir aí uma forma de o utilizador alterar a língua na qual quer ver o site. Mas neste caso ainda não encontrei qualquer informação sobre como usar uma variável de sessão que daria imenso jeito.

O controlador único que estou a falar é para os pedidos ao site, vulgo: navegação

Isto é, tenho um controlador que, consoante a função pedida irá obter o conteúdo correcto a enviar para a vista, isto porque a vista é sempre igual só muda o texto e título da página. E existe apenas uma vista que recebe os dados e apenas os apresenta.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

.. E que se leres o fórum deles, a maioria dos developers envolvidos no CI não recomenda o seu uso .. Procura lá por uma alternativa, caso queiras algo realmente bom e funcional :(

Tens mais informação sobre isso? Vejo alguns a perguntar e a terem problemas com o sistema de sessões mas ainda não encontrei quem dissesse para não usar o sistema do CI, embora existam alguns a indicar bibliotecas alternativas.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Tens mais informação sobre isso? Vejo alguns a perguntar e a terem problemas com o sistema de sessões mas ainda não encontrei quem dissesse para não usar o sistema do CI, embora existam alguns a indicar bibliotecas alternativas.

Se leres bem as entradas do forum, tão lá gajos da EllisLab a dizer que há alternativas mais viáveis ..

http://codeigniter.com/forums/viewthread/86841/

Mas atenção, não testei a class nova desta ultima versão, só da 1.6.x, portanto não sei nada sobre ela ..

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Ninguem diz nada de mal da classe de sessões do CI para alem de tu teres perguntado por uma alternativa robusta.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Ninguem diz nada de mal da classe de sessões do CI para alem de tu teres perguntado por uma alternativa robusta.

Sim, não me apeteceu procurar pelos posts onde vi essas discussões, mas eu encontrei na altura, por isso é que escrevi esse post .. A classe deles aprensentava algumas limitações e problemas, e de modo geral a EllisLab só a aconselhava para sites comuns, sistemas mais carentes de segurança e coisas do género tinham outras alternativas da comunidade ..

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Neste caso a versão que estou a usar é mesmo da 1.7, que pelo que vi é uma nova versão, e pelo que li apresenta melhorias em relação às anteriores.

Pela pesquisa que fiz no fórum, das várias páginas que li, apanhei muito tópico sobre a classe de sessões, mas sempre sobre alguma falha na sua utilização.

Bem, acho que para o que eu quero isto servirá perfeitamente.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Qualquer uma das classes d sessao da CI (oficial ou não) não preenche os requesitos necessários para grandes aplicações (algo do tipo do deviantart) tendo os conhecimentos necessarios o melhor é fazer a vossa, de resto nada a apontar a framework.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Neste caso a aplicação não é grande, e pelo que vi tem tudo o que preciso, eventualmente noutra situação poderá ficar aquém do que preciso mas para já, tem tudo. Aliás, não fosse um pormenor menor, nem iria precisar de sessões.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

ésta é uma class de sessões que eu encontrei num forum para a CI, é mais ou menos igual a original mas trabalha com sessões server side

<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');
/**
* Code Igniter
*
* An open source application development framework for PHP 4.3.2 or newer
*
* @package     CodeIgniter
* @author      Dariusz Debowczyk
* @copyright   Copyright (c) 2006, D.Debowczyk
* @license     http://www.codeignitor.com/user_guide/license.html
* @link        http://www.codeigniter.com
* @since       Version 1.0
* @filesource
*/

// ------------------------------------------------------------------------

/**
* Session class using native PHP session features and hardened against session fixation.
*
* @package     CodeIgniter
* @subpackage  Libraries
* @category    Sessions
* @author      Dariusz Debowczyk
* @link        http://www.codeigniter.com/user_guide/libraries/sessions.html
*/
class CI_Session {

private $flash_key = 'flash'; // prefix for "flash" variables (eg. flash:new:message)

function CI_Session()
{
	$this->object =& get_instance();
	log_message('debug', "Native_session Class Initialized");
	$this->_sess_run();
}

/**
    * Starts up the session system for current request
    */
function _sess_run()
{
	session_start();

	if (get_cookie('session_cookie'))
		$this->set_userdata(unserialize(get_cookie('session_cookie')));

	if (is_numeric($this->object->config->item('sess_expiration')))
	{
		if ($this->object->config->item('sess_expiration') > 0)
		{
			$this->session_id_ttl = $this->object->config->item('sess_expiration');
		}
		else
		{
			$this->session_id_ttl = (60*60*24*365*2);
		}
	}

	// check if session id needs regeneration
	if ( $this->_session_id_expired() )
	{
		// regenerate session id (session data stays the
		// same, but old session storage is destroyed)
		$this->regenerate_id();
	}

	// delete old flashdata (from last request)
	$this->_flashdata_sweep();

	// mark all new flashdata as old (data will be deleted before next request)
	$this->_flashdata_mark();
}

/**
    * Checks if session has expired
    */
function _session_id_expired()
{
	if ( !isset( $_SESSION['regenerated'] ) )
	{
		$_SESSION['regenerated'] = time();
		return false;
	}

	$expiry_time = time() - $this->session_id_ttl;

	if ( $_SESSION['regenerated'] <=  $expiry_time )
	{
		return true;
	}

	return false;
}

/**
    * Regenerates session id
    */
function regenerate_id()
{
	// copy old session data, including its id
	$old_session_id = session_id();
	$old_session_data = $_SESSION;

	// regenerate session id and store it
	session_regenerate_id();
	$new_session_id = session_id();

	// switch to the old session and destroy its storage
	session_id($old_session_id);
	session_destroy();

	// switch back to the new session id and send the cookie
	session_id($new_session_id);
	session_start();

	// restore the old session data into the new session
	$_SESSION = $old_session_data;

	// update the session creation time
	$_SESSION['regenerated'] = time();

	// session_write_close() patch based on this thread
	// http://www.codeigniter.com/forums/viewthread/1624/
	// there is a question mark ?? as to side affects

	// end the current session and store session data.
	session_write_close();
}

/**
    * Destroys the session and erases session storage
    */
function destroy()
{	
	unset($_SESSION);
	delete_cookie('session_cookie');
	session_destroy();
}

/**
    * Erases given session attributes
    */
function unset_userdata($newdata = array())
{
	if (is_string($newdata))
	{
		$newdata = array($newdata => '');
	}

	if (count($newdata) > 0)
	{
		foreach ($newdata as $key => $val)
		{
			unset($_SESSION[$key]);
		}
	}
}

/**
    * Reads given session attribute value
    */    
function userdata($item)
{
	if($item == 'session_id'){ //added for backward-compatibility
		return session_id();
	}else{
		return ( ! isset($_SESSION[$item])) ? false : $_SESSION[$item];
	}
}

/**
    * Sets session attributes to the given values
    */
function set_userdata($newdata = array(), $newval = '')
{
	if (is_string($newdata))
	{
		$newdata = array($newdata => $newval);
	}

	if (count($newdata) > 0)
	{
		foreach ($newdata as $key => $val)
		{
			$_SESSION[$key] = $val;
		}
	}
}

/**
    * Sets "flash" data which will be available only in next request (then it will
    * be deleted from session). You can use it to implement "Save succeeded" messages
    * after redirect.
    */
function set_flashdata($key, $value)
{
	$flash_key = $this->flash_key.':new:'.$key;
	$this->set_userdata($flash_key, $value);
}

/**
    * Keeps existing "flash" data available to next request.
    */
function keep_flashdata($key)
{
	$old_flash_key = $this->flash_key.':old:'.$key;
	$value = $this->userdata($old_flash_key);

	$new_flash_key = $this->flash_key.':new:'.$key;
	$this->set_userdata($new_flash_key, $value);
}

/**
    * Returns "flash" data for the given key.
    */
function flashdata($key)
{
	$flash_key = $this->flash_key.':old:'.$key;
	return $this->userdata($flash_key);
}

/**
    * PRIVATE: Internal method - marks "flash" session attributes as 'old'
    */
function _flashdata_mark()
{
	foreach ($_SESSION as $name => $value)
	{
		$parts = explode(':new:', $name);
		if (is_array($parts) && count($parts) == 2)
		{
			$new_name = $this->flash_key.':old:'.$parts[1];
			$this->set_userdata($new_name, $value);
			$this->unset_userdata($name);
		}
	}
}

/**
    * PRIVATE: Internal method - removes "flash" session marked as 'old'
    */
function _flashdata_sweep()
{
	foreach ($_SESSION as $name => $value)
	{
		$parts = explode(':old:', $name);
		if (is_array($parts) && count($parts) == 2 && $parts[0] == $this->flash_key)
		{
			$this->unset_userdata($name);
		}
	}
}
}
?>

não testei espero que funcione

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora