Diskuze: header('Location: ); nefunguje
V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.
Neaktivní uživatel:24.1.2018 14:48
Header je možné nastavit pouze v případě, že jsi neodeslal žádný text. Pokud ti to píše "warning cannot modify header information - headers already sent by", pak jsi někde něco vypsal a proto to nefunguje.
Posílám celý kod. Nejsem si jist tím co jsi napsal, header mám myslím
umístěn správně.
<?php
session_start();
require('Db.php');
Db::connect('wm46.wedos.net', 'd52393_pes', 'w52393_pes', '?????????');
if (isset($_SESSION['uzivatel_id']))
{
header('Location: http://quickbuy.cz/indexpokus.php');
exit();
}
if ($_POST)
{
$uzivatel = Db::queryOne('
SELECT uzivatele_id, admin
FROM uzivatele
WHERE jmeno=? AND heslo=SHA1(?)
', $_POST['jmeno'], $_POST['heslo'] . "t&#ssdf54gh");
if (!$uzivatel)
$zprava = 'Neplatné uživatelské jméno nebo heslo';
else
{
$_SESSION['uzivatel_id'] = $uzivatel['uzivatele_id'];
$_SESSION['uzivatel_jmeno'] = $_POST['jmeno'];
$_SESSION['uzivatel_admin'] = $uzivatel['admin'];
header('Location: http://quickbuy.cz/indexpokus.php');
exit();
}
}
?>
<!DOCTYPE html>
<html lang="cs-cz">
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="styl.css" type="text/css" />
<title>Přihlášení do administrace</title>
</head>
<body>
<article>
<div id="centrovac">
<header>
<h1>Přihlášení do administrace</h1>
</header>
<section>
<?php
if (isset($zprava))
echo('<p>' . $zprava . '</p>');
?>
<form method="post">
Jméno<br />
<input type="text" name="jmeno" /><br />
Heslo<br />
<input type="password" name="heslo" /><br />
<input type="submit" value="Přihlásit" />
</form>
</section>
<div class="cistic"></div>
</div>
</article>
</body>
</html>
Uživatel sítě :24.1.2018 16:00
Co ten býlí znak nad session_start()? Ten by tu chybu mohl způsobit.
Roman Kulhánek:24.1.2018 16:26
Ahoj, asi ne, dal jsem pryč tu mezeru ale pořád vypisuje chybu na řádku 28 což je zde.
$_SESSION['uzivatel_id'] = $uzivatel['uzivatele_id'];
$_SESSION['uzivatel_jmeno'] = $_POST['jmeno'];
$_SESSION['uzivatel_admin'] = $uzivatel['admin'];
header('Location: http://quickbuy.cz/indexpokus.php'); ZDE
Uživatel sítě :24.1.2018 16:32
Tak mě ještě napadají BOM značky, je možné, že je máš v IDE povolené.
Roman Kulhánek:24.1.2018 16:47
Tak nyní to vypadá takto. Myslím že sem všecky bílé odstranil, podle návodu
https://kb.wedos.com/forum/topic/444/diskuze-ke-clanku-pspad-problem-se-soubory-v-utf-8.html?sid=P029c82TcGXD3nWbYRRerEWL9vYIN1meUmaYp7SKO3tQk
jsem myslel že vypnu tu fajfečku kodování ale vypnutá už byla, takže asi se to dělá bez těch Bom, nevím jak to ověřit.
<?php
session_start();
require('Db.php');
Db::connect('wm46.wedos.net', 'd52393_pes', 'w52393_pes', '9bkzzu9528K!');
if (isset($_SESSION['uzivatel_id']))
{
header('Location: indexpokus.php');
exit();
}
if ($_POST)
{
$uzivatel = Db::queryOne('
SELECT uzivatele_id, admin
FROM uzivatele
WHERE jmeno=? AND heslo=SHA1(?)
', $_POST['jmeno'], $_POST['heslo'] . "t&#ssdf54gh");
if (!$uzivatel)
$zprava = 'Neplatné uživatelské jméno nebo heslo';
else
{
$_SESSION['uzivatel_id'] = $uzivatel['uzivatele_id'];
$_SESSION['uzivatel_jmeno'] = $_POST['jmeno'];
$_SESSION['uzivatel_admin'] = $uzivatel['admin'];
header('Location: indexpokus.php');
exit();
}
}
?>
<!DOCTYPE html>
<html lang="cs-cz">
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="styl.css" type="text/css" />
<title>Přihlášení do administrace</title>
</head>
<body>
<article>
<div id="centrovac">
<header>
<h1>Přihlášení do administrace</h1>
</header>
<section>
<?php
if (isset($zprava))
echo('<p>' . $zprava . '</p>');
?>
<form method="post">
Jméno<br />
<input type="text" name="jmeno" /><br />
Heslo<br />
<input type="password" name="heslo" /><br />
<input type="submit" value="Přihlásit" />
</form>
</section>
<div class="cistic"></div>
</div>
</article>
</body>
</html>
Matúš Petrofčík:24.1.2018 20:47
Co ten býlí znak nad session_start()? Ten by tu chybu mohl způsobit.
To je v PHP a to nevadí, medzery a tabulátory sa v PHP kódu ignorujú.
Matúš Petrofčík:24.1.2018 20:50
Tak mě ještě napadají BOM značky, je možné, že je máš v IDE povolené.
Imho málo pravdepodobné. Ale dobrý point.
Matúš Petrofčík:24.1.2018 20:59
Trochu buzerácie na začiatok:
Romane prosím ťa, nauč sa na sieti používať tagy pre kód, inak sa z toho
zbláznime Ukážku použitia
máš v obrázku a aby si to nemusel písať, môžeš použiť tlačítko medzi
tlačítkom na smajlíky a tučné písmo
Každopádne k téme:
Predtým než chceš vyvolať presmerovanie sa nesmie vypísať žiaden znak tak
ako píše Neaktivní uživatel. Teda žiadne echo "abc";
a žiaden html
kód pred poslaním headeru s novou lokáciou a podobne.
Z kódu ma napadá, že tá trieda ktorú tam requiruješ (DB.php) môže
mať na konci súboru za ?>
nejaký znak (medzeru alebo
enter).
<?php
class DB
{
// ...
}
?>
[namiesto tohto textu tu je medzera, enter, iný znak]
Ešte doplním, že ak súbor má v sebe IBA PHP kód, tak na konci súboru nemusíš dávať ?> a tieto problémy by nemuseli nastávať.
Uživatel sítě :24.1.2018 21:11
S kombinací BOM tuším, že právě ano nepletu-li se?
Ah díky, nemohl sem najít nápovědu pro fórum, chtěl sem tak učinit hned na ty kódy.
Prosím tě DB.php používám odsud, na konci ?> vůbec není. Ovšem problém bude asi opravdu někde v něm, protože to přesměrování mi nefunguje odnikud nikam, všechny stránky chybu hlásí.
<?php
class Db
{
/**
* @var PDO Databázové spojení
*/
private static $connection;
/**
* @var array Výchozí nastavení ovladače
*/
private static $options = array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING,
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8",
PDO::ATTR_EMULATE_PREPARES => false,
);
/**
* Připojí se k databázi pomocí daných údajů
* @param string $host Název hostitele
* @param string $database Název databáze
* @param string $user Uživatelské jméno
* @param string $password Heslo
*/
public static function connect($host, $database, $user, $password)
{
if (!isset(self::$connection)) {
$dsn = "mysql:host=$host;dbname=$database";
self::$connection = new PDO($dsn, $user, $password, self::$options);
}
}
/**
* Spustí dotaz a vrátí PDO statement
* @param array $params Pole, kde je prvním prvkem dotaz a dalšími jsou parametry
* @return \PDOStatement PDO statement
*/
private static function executeStatement($params)
{
$query = array_shift($params);
$statement = self::$connection->prepare($query);
$statement->execute($params);
return $statement;
}
/**
* Spustí dotaz a vrátí počet ovlivněných řádků. Dále se předá libovolný počet dalších parametrů.
* @param string $query Dotaz
* @return int Počet ovlivněných řádků
*/
public static function query($query) {
$statement = self::executeStatement(func_get_args());
return $statement->rowCount();
}
/**
* Spustí dotaz a vrátí z něj první sloupec prvního řádku. Dále se předá libovolný počet dalších parametrů.
* @param string $query Dotaz
* @return mixed Hodnota prvního sloupce z prvního řádku
*/
public static function querySingle($query) {
$statement = self::executeStatement(func_get_args());
$data = $statement->fetch();
return $data[0];
}
/**
* Spustí dotaz a vrátí z něj první řádek. Dále se předá libovolný počet dalších parametrů.
* @param string $query Dotaz
* @return mixed Pole výsledků nebo false při neúspěchu
*/
public static function queryOne($query) {
$statement = self::executeStatement(func_get_args());
return $statement->fetch(PDO::FETCH_ASSOC);
}
/**
* Spustí dotaz a vrátí všechny jeho řádky jako pole asociativních polí. Dále se předá libovolný počet dalších parametrů.
* @param string $query Dotaz
* @return mixed Pole řádků enbo false při neúspěchu
*/
public static function queryAll($query) {
$statement = self::executeStatement(func_get_args());
return $statement->fetchAll(PDO::FETCH_ASSOC);
}
/**
* Umožňuje snadné vložení záznamu do databáze pomocí asociativního pole
* @param string $table Název tabulky
* @param array $data Asociativní pole, kde jsou klíče sloupce a hodnoty hodnoty
* @return int Počet ovlivněných řádků
*/
public static function insert($table, $data) {
$keys = array_keys($data);
self::checkIdentifiers(array($table) + $keys);
$query = "
INSERT INTO `$table` (`" . implode('`, `', $keys) . "`)
VALUES (" . str_repeat('?,', count($data) - 1) . "?)
";
$params = array_merge(array($query), array_values($data));
$statement = self::executeStatement($params);
return $statement->rowCount();
}
/**
* Umožňuje snadnou modifikaci záznamu v databázi pomocí asociativního pole
* @param string $table Název tabulky
* @param array $data Asociativní pole, kde jsou klíče sloupce a hodnoty hodnoty
* @param string $condition Řetězec s SQL podmínkou (WHERE)
* @return mixed
*/
public static function update($table, $data, $condition) {
$keys = array_keys($data);
self::checkIdentifiers(array($table) + $keys);
$query = "
UPDATE `$table` SET `".
implode('` = ?, `', array_keys($data)) . "` = ?
$condition
";
$params = array_merge(array($query), array_values($data), array_slice(func_get_args(), 3));
$statement = self::executeStatement($params);
return $statement->rowCount();
}
/**
* Vrátí poslední ID posledního záznamu vloženého pomocí INSERT
* @return mixed Id posledního záznamu
*/
public static function getLastId()
{
return self::$connection->lastInsertId();
}
/**
* Ošetří string proti SQL injekci
* @param string $string Řetězec
* @return mixed Ošetřený řetězec
*/
public static function quote($string)
{
return self::$connection->quote($string);
}
/**
* Zkontroluje, zda identifikátory odpovídají formátu identifikátorů
* @param array $identifiers Pole identifikátorů
* @throws \Exception
*/
private static function checkIdentifiers($identifiers)
{
foreach ($identifiers as $identifier)
{
if (!preg_match('/^[a-zA-Z0-9\_\-]+$/u', $identifier))
throw new Exception('Dangerous identifier in SQL query');
}
}
}
Matúš Petrofčík:24.1.2018 21:23
S kombinací BOM tuším, že právě ano nepletu-li se?
Tak to teda neviem. Nikdy v živote som s týmto problém nemal.
Matúš Petrofčík:24.1.2018 21:25
Aj som si tie tvoje kódy skopíroval do IDE a neviem čím by to ešte mohlo byť.
Napadá mi akurát, že by mohol server nejaký header predtým
nastavovať?
Prípadne zlé kódovanie súboru?
Prípadne ten BOM?
A pred tým <?php
sa tiež nenachádza nejaký prázdny
riadok?
Chcem ísť spať, takže ťa odkážem na túto odpoveď: https://stackoverflow.com/a/8028987 (anglicky)
Roman Kulhánek:24.1.2018 21:30
Díky počtu si, ale samo sem už hledal co jsem mohl než sem napsal
Matúš Petrofčík:24.1.2018 21:31
V tvojom prípade mi teraz napadla možnosť, že
session_start()
nastaví header, a potom tým presmerovaním
posielaš header druhý... teoreticky by to mohlo byť ono.
Vyřešeno asi. Odebráním mezery za <?php . Vypadá že jede přesměrování.
<?php
class Db
{
Matúš Petrofčík:24.1.2018 21:35
A hele, z toho čo si mi poslal
Warning: Cannot modify header information - headers already sent by (output started at /data/web/virtuals/52393/virtual/www/domains/quickbuy.cz/Db.php:1) in /data/web/virtuals/52393/virtual/www/domains/quickbuy.cz/prihlaseni.php on line 26
Hlavne ma zaujala táto časť:
output started at ... Db.php:1
Imho to znamená, že máš v súbore Db.php pred/za <?php
nejaký znak pretože tam začalo vypisovanie obsahu, a to bráni tomu
následnému headeru.
26 je řádek s header('Location: indexpokus.php');
To je miesto kde sa Warning objavil, ale to neznamená že je chyba práve tam.
+20 Zkušeností
+2,50 Kč
Zobrazeno 20 zpráv z 20.