Zend FR

Consultez la FAQ sur le ZF avant de poster une question

Vous n'êtes pas identifié.

#1 04-12-2008 15:47:20

ramsesservices
Membre
Date d'inscription: 13-08-2008
Messages: 10

[Résolu] Auth et "Headers already sent"

Bonjour,

Voilà j'ai un petit soucis avec une procédure de login. Lorsque le formulaire est envoyé je reçois une erreur me disant 'Headers already sent'.

Le problème vient au moment du redirect quand l'authentification réussi apparemment.

Voici le code :

Code:

    public function loginAction ()
    {
        $this->view->message = '';
        $this->view->username = '';
        if ($this->_request->isPost()) {
            Zend_Loader::loadClass('Zend_Filter_StripTags');
            $f = new Zend_Filter_StripTags();
            $username = $f->filter($this->_request->getPost('username'));
            $password = $f->filter($this->_request->getPost('passwd'));
            if (empty($username)) {
                $this->view->errmsg = "Veuillez entrer un nom d'utilisateur.";
            } else {
                $this->view->username = $username;
                Zend_Loader::loadClass('Zend_Auth_Adapter_DbTable');
                $dbAdapter = Zend_Db_Table::getDefaultAdapter();
                $authAdapter = new Zend_Auth_Adapter_DbTable($dbAdapter);
                $authAdapter->setTableName('users');
                $authAdapter->setIdentityColumn('username');
                $authAdapter->setCredentialColumn('password');
                $authAdapter->setIdentity($username);
                $authAdapter->setCredential($password);
                $auth_user = $authAdapter->getResultRowObject('archived');
                if ($auth_user->archived) {
                    $result = false;
                } else {
                    $result = $this->auth->authenticate($authAdapter);
                }
                if ($result->isValid()) {
                    $data = $authAdapter->getResultRowObject(null, 'password');
                    if (!$data->archived) {
                        $this->auth->getStorage()->write($data);
                        $this->logger->debug("Successful Login -> " . $data->username);
                        $this->_redirect('/customer');
                    } else {
                        $this->view->errmsg = "L'utilisateur $username n'existe pas ou est désactivé!";
                    }
                } else {
                    $this->view->errmsg = "Le nom d'utilisateur et/ou le mot de passe est incorrect.";
                }
            }
        }
        $this->view->title = 'Connexion';
        $this->render();
    }

Merci pour votre aide

Dernière modification par ramsesservices (09-12-2008 14:21:25)

Hors ligne

 

#2 04-12-2008 16:20:17

Julien
Membre
Date d'inscription: 16-03-2007
Messages: 501

Re: [Résolu] Auth et "Headers already sent"

Un tag de fin PHP oublié dans un fichier ?

Hors ligne

 

#3 04-12-2008 17:15:42

nORKy
Membre
Date d'inscription: 06-03-2008
Messages: 1098

Re: [Résolu] Auth et "Headers already sent"

Julien a écrit:

Un tag de fin PHP oublié dans un fichier ?

hmm.. C'est pas le contraire ?? Un tag placé alors qu'il ne le devrait pas ??

Si tu places un tag ?> en fin de fichier, il y a des chances justement qu'il y est un saut de ligne rebelle derrière.


----
Gruiiik !

Hors ligne

 

#4 04-12-2008 18:20:36

NewSky
Membre
Date d'inscription: 17-12-2007
Messages: 79

Re: [Résolu] Auth et "Headers already sent"

Oui, il me semble que nORKy a raison, d'ailleurs, c'est dans la doc de zend ici.

Hors ligne

 

#5 04-12-2008 18:55:23

mikaelkael
Administrateur
Lieu: Donges
Date d'inscription: 18-06-2007
Messages: 1176
Site web

Re: [Résolu] Auth et "Headers already sent"

Hello,

C'est bien ce que dit Julien, le tag est là alors qu'il ne devrait pas, donc il a été oublié wink .

A+


Less code = less bugs
Contributeur ZF - ZCE - ZFCE - Doc ZF (CHM & PDF) - Vice-trésorier AFUP 2011
Ubuntu 11.04 - ZendServer

Hors ligne

 

#6 04-12-2008 19:12:48

sekaijin
Membre
Date d'inscription: 17-08-2007
Messages: 1137

Re: [Résolu] Auth et "Headers already sent"

il y a aussi que tu fais un rendu de la vue pour rien
le redirect continue le script et donc tu passe par ton rendu
il y a un redirect plus efficient
GoToUrlAndExit
dans ce cas la redirection est immédiate et ton script s'arrête là.

j'ai surchargé mon redirect pour qu'il soit immédiat (c'est peut être un peu brutal)
au passage il tien compte de ma classe de débug (pour faire des traces) et donc dans ce cas m'affiche le lien sur lequel doit avoir lieu le redirect
cela permet d'avancer d'action en action à la main lorsqu'on à mis des traces

Code:

    protected function _redirect($url, array $options = array())
    {
        // lien de déblocage suite à Debug
        if (class_exists('Fast_Debug')&&Fast_Debug::isStarted()) {
            $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
            $viewRenderer->setNoRender(true);
            Fast_Debug::show("Mode debug actif impossible de charger l'url : <a style='color:red; background-color:yellow' href='" . $this->_request->getBaseUrl() . $url . "'>" . $this->_request->getBaseUrl() . $url . "</a>", $options);
            exit();
        } else {
            $this->_helper->redirector->gotoUrlAndExit($url, $options);
        }
        $this->_redirected = true;
    }

A+JYT

Hors ligne

 

#7 05-12-2008 12:50:26

ramsesservices
Membre
Date d'inscription: 13-08-2008
Messages: 10

Re: [Résolu] Auth et "Headers already sent"

Pour la balise de finb je pensais qu'il n'y avait quand dans le bootstrap (index.php) que c'était important.
J'ai fais le test de les enlever tous mais sans résultat.

Le pire c'est que le même code sur une autre machine (Windows) fonctionne bien lui.

Sekaijin,

Merci pour l'info, je pensais que redirect stoppait le processus. ZF est génial mais ce genre de chose contribue à la perte de performance qu'on lui reproche trop souvent d'ailleurs.

Hors ligne

 

#8 05-12-2008 12:56:52

ramsesservices
Membre
Date d'inscription: 13-08-2008
Messages: 10

Re: [Résolu] Auth et "Headers already sent"

Ce qui me semble étrange c'est que j'ai l'impression d'avoir une étoile dans mes pages sans pour autant savoir d'où elle vient.
Voici le code de mon error.phtml par exemple:

Code:

<table cellpadding="0" cellspacing="0" border="0" width="100%">
    <tr>
        <td>
            <?php echo $this->content ?>
        </td>
    </tr>
<?php if ($this->showDetails){ ?>
    <tr>
        <td>
            <h1>Détails de l'erreur :</h1>
            <table cellspacing="0" cellpadding="0" id="msg"    class="failed">
                <tr>
                    <td>
                    <p><?php echo $this->errorMessage ?></p>
                    <p>&nbsp;</p>
                    <p><?php echo nl2br($this->errorStackTrace) ?></p>
                    </td>
                </tr>
            </table>
        </td>
    </tr>
<?php } ?>
</table>

Et voici le code de la page que je reçois :

Code:

*<table cellpadding="0" cellspacing="0" border="0" width="100%">
    <tr>
        <td>
            <h1>Erreur</h1>
<p>Une erreur est survenue lors de votre requ�te. Veuillez r�essayer s.v.p.<br />Si le probl�me persiste, contactez votre administrateur.</p>        </td>
    </tr>
    <tr>

        <td>
            <h1>Détails de l'erreur :</h1>
            <table cellspacing="0" cellpadding="0" id="msg"    class="failed">
                <tr>
                    <td>
                    <p>Cannot send headers; headers already sent in /Users/NiGhMa/Documents/Clients/BCFD/dev/CustMgnt/application/controllers/AuthController.php, line 1</p>
                    <p>&nbsp;</p>
                    <p>#0 /Users/NiGhMa/dev/ZF/1.7.0/library/Zend/Controller/Response/Abstract.php(147): Zend_Controller_Response_Abstract->canSendHeaders(true)<br />

#1 /Users/NiGhMa/dev/ZF/1.7.0/library/Zend/Controller/Action/Helper/Redirector.php(201): Zend_Controller_Response_Abstract->setRedirect('/customer', 302)<br />
#2 /Users/NiGhMa/dev/ZF/1.7.0/library/Zend/Controller/Action/Helper/Redirector.php(348): Zend_Controller_Action_Helper_Redirector->_redirect('/customer')<br />
#3 /Users/NiGhMa/dev/ZF/1.7.0/library/Zend/Controller/Action/Helper/Redirector.php(431): Zend_Controller_Action_Helper_Redirector->setGotoUrl('/customer', Array)<br />
#4 /Users/NiGhMa/dev/ZF/1.7.0/library/Zend/Controller/Action/Helper/Redirector.php(447): Zend_Controller_Action_Helper_Redirector->gotoUrl('/customer', Array)<br />
#5 /Users/NiGhMa/Documents/Clients/BCFD/dev/CustMgnt/application/controllers/AuthController.php(61): Zend_Controller_Action_Helper_Redirector->gotoUrlAndExit('/customer')<br />
#6 /Users/NiGhMa/dev/ZF/1.7.0/library/Zend/Controller/Action.php(503): AuthController->loginAction()<br />
#7 /Users/NiGhMa/dev/ZF/1.7.0/library/Zend/Controller/Dispatcher/Standard.php(285): Zend_Controller_Action->dispatch('loginAction')<br />
#8 /Users/NiGhMa/dev/ZF/1.7.0/library/Zend/Controller/Front.php(934): Zend_Controller_Dispatcher_Standard->dispatch(Object(Zend_Controller_Request_Http), Object(Zend_Controller_Response_Http))<br />
#9 /Users/NiGhMa/Documents/Clients/BCFD/dev/CustMgnt/html/index.php(87): Zend_Controller_Front->dispatch()<br />

#10 {main}</p>
                    </td>
                </tr>
            </table>
        </td>
    </tr>
</table>

Vous voyez la petite '*' juste comme premier caractère ? Je ne vois pas d'où elle vient.

Une idée ?

Dernière modification par ramsesservices (05-12-2008 12:57:24)

Hors ligne

 

#9 05-12-2008 17:57:37

sekaijin
Membre
Date d'inscription: 17-08-2007
Messages: 1137

Re: [Résolu] Auth et "Headers already sent"

deux solution soit tu fais un goToUrlAndExit soit tu gère correctement ton rendu
donc si tu fais une redirection tu mets un setNoViewRender et pour le reste tu ne le mets pas dans la suite du code mais dans un else.

tu n'as pas à passer dans le render lorsque tu fais un redirect c'est logique tu ne peux pas demander une redirection et afficher quelque chose

pour ma part je n'ai jamais d'action qui fasse un rendu et une redirection
les action qui font un rendu ne font pas de redirection et vice versa.

dans ton cas tu fais ton test et dans un cas tu fais un redirect vers customer et dans lautre tu fais une redirection vers showLogin ton action ne fais donc aucun rendu (et tu lui mets bien un noviewrenderer)

et dans l'action showLogin tu ne fais que ton rendu c'est beaucoup plus simple à gérer
ça évite les problèmes

mon Login_AuthController

Code:

    public function logoutAction()
    {
        $this->model->clearIdentity();
        $returnPath = $this->_request->get('returnPath', null);
        if (! $returnPath) {
            $returnPath = $this->_to('showLogin');
        }
        $this->_redirect($returnPath);
    }

    public function showLoginAction() {
        $this->_createContext();
        if (isset($this->history->previous->path)) {
            $this->context->returnPath = $this->history->previous->path;
        } else {
            $this->context->returnPath = '/';
        }

        $this->view->page->title = 'Connexion';
        $returnPath = $this->_request->get('returnPath', null);
        if ($returnPath) {
            $this->view->auth->cancelAction = $this->view->baseUrl.$returnPath;
        }
        $this->view->auth->getPwdAction =  $this->view->baseUrl.$this->_to('getpwd');
        $this->view->auth->formAction = $this->view->baseUrl.$this->_to('checkLogin');

        if (!isset($this->context->formData)) {
            $this->context->formData = new StdClass();
        }
        $this->view->form = $this->context->formData;
        $this->view->formErrors = $this->context->formErrors;

        $this->view->useDecoration = true;

        $params = $this->getParams('global');
        if (!$params['show_menu']) {
            unset($this->menu);
        }
        $this->render('login');
    }

    public function checkLoginAction() {
        $this->_linkContext();

        Zend_Loader::loadClass('Zend_Filter');
        Zend_Loader::loadClass('Zend_Filter_StripTags');
        $filterChain = new Zend_Filter();
        if ($form = $this->_request->get('form'))
        foreach ($form as $key=>$value) {
            $this->context->formData->$key = trim($filterChain->filter($value));
        }
        $this->context->formData->login = strtolower($this->context->formData->login);
        $this->context->formData->password = strtolower($this->context->formData->password);
        $ok = true;
        if (!isset($this->context->formData->login)||''==$this->context->formData->login) {
            $this->_messenger->addError($this->_messages['login_need']);
            $this->context->formErrors->login[] = $this->_messages['login_need'];
            $ok = false;
        }
        if (!isset($this->context->formData->password)||''==$this->context->formData->password) {
            $this->_messenger->addError($this->_messages['pass_need']);
            $this->context->formErrors->password[] = $this->_messages['pass_need'];
            $ok = false;
        }
        if ($ok) {
            $redirect = $this->_to('login');
        } else {
            $redirect = $this->_to('showLogin');
        }
        #Fast_Debug::show('$redirect',$redirect);
        $this->_redirect($redirect);
    }

    public function loginAction() {
        $this->_linkContext();
        if (isset($this->context->formData)) {

            $result = $this->model->authenticate($this->context->formData->login,
            $this->context->formData->password);
            if ($result->isValid()) {
                // stockage des données d'identification
                $this->model->storeLoggedUser();
                // on passe au choix du profil
                $redirect = $this->_to('showRoles');
                // ------------------------------
            } else {
                $this->_messenger->addError($this->_messages['unknow']);
                $redirect = $this->_to('showLogin');
            }
        } else {
            $this->_popHistory();
            $this->_messenger->addError($this->_messages['unknow_user']);
            $redirect = $this->_to('showLogin');
        }
        $this->_redirect($redirect);
    }

...

A+
JYT

Hors ligne

 

#10 08-12-2008 09:51:23

Mr.MoOx
Administrateur
Lieu: Toulouse
Date d'inscription: 27-03-2007
Messages: 1444
Site web

Re: [Résolu] Auth et "Headers already sent"

Vous voyez la petite '*' juste comme premier caractère ? Je ne vois pas d'où elle vient.

Utf8- avec BOM, mieux vaut utiliser le sans BOM.

Hors ligne

 

#11 09-12-2008 13:49:24

ramsesservices
Membre
Date d'inscription: 13-08-2008
Messages: 10

Re: [Résolu] Auth et "Headers already sent"

J'aimerais revenir sur ce BOM. A quel endroit, dois-je spécifier cela ? Dans mon bootstrap ? Dans mes views (*.phtml) ? Ou ailleurs ?

Je développe avec Zend Studio Professionnal for Eclipse.

Merci d'avance

Hors ligne

 

#12 09-12-2008 14:03:34

ramsesservices
Membre
Date d'inscription: 13-08-2008
Messages: 10

Re: [Résolu] Auth et "Headers already sent"

Sekaijin,

Merci pour les infos. J'ai essayé de remplacer le $this->_redirect... par $this->_helper->redirector->gotoUrlAndExit('/customer'); mais rien ne change. C'est comme si quelque chose était envoyé dans le header avant cete ligne de commande. Le problème c'est ue je vois vraiment pas où.

Je remets mon code ci-dessous. Peut-être vois-tu ce qui est juste devant mon nez et que je n'arrive pas à voir ^^

Merci

Code:

public function loginAction ()
    {
        $this->view->message = '';
        $this->view->username = '';
        if ($this->_request->isPost()) {
            Zend_Loader::loadClass('Zend_Filter_StripTags');
            $f = new Zend_Filter_StripTags();
            $username = $f->filter($this->_request->getPost('username'));
            $password = $f->filter($this->_request->getPost('passwd'));
            if (empty($username)) {
                $this->view->errmsg = "Veuillez entrer un nom d'utilisateur.";
            } else {
                $this->view->username = $username;
                Zend_Loader::loadClass('Zend_Auth_Adapter_DbTable');
                $dbAdapter = Zend_Db_Table::getDefaultAdapter();
                $authAdapter = new Zend_Auth_Adapter_DbTable($dbAdapter);
                $authAdapter->setTableName('users');
                $authAdapter->setIdentityColumn('username');
                $authAdapter->setCredentialColumn('password');
                $authAdapter->setIdentity($username);
                $authAdapter->setCredential($password);
                $auth_user = $authAdapter->getResultRowObject('archived');
                if ($auth_user->archived) {
                    $result = false;
                } else {
                    $result = $this->auth->authenticate($authAdapter);
                }
                if ($result->isValid()) {
                    $data = $authAdapter->getResultRowObject(null, 'password');
                    if (!$data->archived) {
                        $this->auth->getStorage()->write($data);
                        $this->logger->debug("Successful Login -> " . $data->username);
                        $this->_helper->redirector->gotoUrlAndExit('/customer');
                    } else {
                        $this->view->errmsg = "L'utilisateur $username n'existe pas ou est désactivé!";
                    }
                } else {
                    $this->view->errmsg = "Le nom d'utilisateur et/ou le mot de passe est incorrect.";
                }
            }
        }
        $this->view->title = 'Connexion';
        $this->render();
    }

Hors ligne

 

#13 09-12-2008 14:24:01

sekaijin
Membre
Date d'inscription: 17-08-2007
Messages: 1137

Re: [Résolu] Auth et "Headers already sent"

il suffit que tu ai un ?> dans un des fichier que tu inclus pour envoyer un _n à ton client est donc tous les headers

Hors ligne

 

#14 09-12-2008 14:24:09

ramsesservices
Membre
Date d'inscription: 13-08-2008
Messages: 10

Re: [Résolu] Auth et "Headers already sent"

Voilà, c'est résolu. Mr.MoOx avait raison.

Mon fichier AuthController.php était "bomé". Mes éditeurs ne me le montraient pas car ils interprétaient le BOM. J'ai donc utiliser un bon "vi" qui m'a fait apparaître la petite étoile comme premier caractère de mon fichier. J'ai donc pu retirer cette étoile avec vi et voilà ça fonctionne.

Pour info, j'ai lu ceci qui m'a aussi adié à comprendre : http://fr.wikipedia.org/wiki/Marque_d%2 … des_octets (dans la rubrique Bogue).

Merci pour vos recherches

Hors ligne

 

#15 09-12-2008 16:39:46

Mr.MoOx
Administrateur
Lieu: Toulouse
Date d'inscription: 27-03-2007
Messages: 1444
Site web

Re: [Résolu] Auth et "Headers already sent"

Eclipse par exemple permet de gérer le BOM, notepad++ aussi.

Hors ligne

 

#16 10-12-2008 08:39:54

nORKy
Membre
Date d'inscription: 06-03-2008
Messages: 1098

Re: [Résolu] Auth et "Headers already sent"

En même temps, si il travaille avec vi... notepad++ il connait pas smile

Faire attention avec vi entre l'encodage des fichiers lus et l'encodage de l'enregistrement des fichiers. C'est 2 options différentes.


----
Gruiiik !

Hors ligne

 

Pied de page des forums

Propulsé par PunBB
© Copyright 2002–2005 Rickard Andersson
Traduction par punbb.fr

Graphisme réalisé par l'agence Rodolphe Eveilleau
Développement par Kitpages