Autor Zpráva
Lucyk
Profil
Prosím o radu, kam a jakým způsobem zapsat funkci str_replace pro řetězec, který se skládá z více proměnných.


Mám stránku, kde vypisuji jednotlivá jména do sloupečku



Na základě výběru jména např. Jindra Josef to vyhodí seznam všech položek, kde je obsaženo toto jméno. Jelikož občas se mohou vyskytnout dvě totožné jména, lišící se rokem, tak používám v dotazu 3 proměnné ($jmeno, $prijmeni, $rok).


Po kliknutí na jméno vyjede následující seznam


A v tomto výsledku nevím, jakým způsobem odstranit z řetězce Josef Jindra 1990 rok. Tzn. aby se vypsalo jen jméno Josef Jindra.


Stará se o to tato část kódu (zkrácená verze)
    $query = mysql_query($co) or die(mysql_error());
    $count = mysql_num_rows($query);
    if($count > 0){
        $search_output2 .= "<hr />$count results for <strong>$celejmeno</strong><hr />";
        while($row = mysql_fetch_array($query)){
            $id = $row["id"];
            
        $search_output2 .= "Item ID:  >";
        } // 


Jedná se o proměnnou $celejmeno, která se skládá z $jmeno, $prijmeni, $rok.


Zkoušela jsem použít str_replace následovně, ale vždy bez úspěchu


Nahrazení čísel v proměnné $celejmeno (zatím jsem to zkoušela jen např. pro číslo 1
$celejmeno = str_replace('1', '' , '$celejmeno');
Tuto část kódu jsem pak zkoušela umístit jak před , tak i za řádek, který vypisuje proměnnou $search_output2.


Pak mě napadlo použít str_replace přímo do následujícího řádku (ale bez úspěchu)
$search_output2 .= "<hr />$count results for <strong>$celejmeno</strong><hr />";
kdy jsem místo $celejmeno vložila výše uvedený kód
$celejmeno = str_replace('1', '' , '$celejmeno');



Lze nějakým způsobem nahradit část proměnné, která je složena z více proměnných?

Děkuji za případné návrhy a komentáře.
Taps
Profil
Zkus
$celejmeno = str_replace('1', '' , $celejmeno);
Tomášeek
Profil
Lucyk:
Není řešením odebrat ty číslice z konce stringu, řešením je zajistit, aby na 4. řádku uvedeného kódu bylo v proměnné jen jméno (rok v proměnné $celejmeno být nemá, což vyplývá jak z jejího pojmenování, tak z logiky věci a problémů, které to přináší, viz ten, co teď řešíš).
Lucyk
Profil
Taps:
Děkuji, Tvůj návrh jsem umístila následovně:
    $query = mysql_query($co) or die(mysql_error());
    $count = mysql_num_rows($query);
    if($count > 0){
        $celejmeno = str_replace('1', '' , $celejmeno);
        $search_output2 .= "<hr />$count results for <strong>$celejmeno</strong><hr />";
        while($row = mysql_fetch_array($query)){
            $id = $row["id"];
            
        $search_output2 .= "Item ID:  >";
        } //
A už to vypisuje to, co dle definování má, tj. bez čísla 1.


Ještě bych se chtěla zeptat, zda jde nějakým způsobem udělat i výpis, kdy rok by se vypsal do závorek, tzn. Josef Jindra (1990)

V str_replace již nelze pracovat s proměnnými samostatně ($jmeno, $prijmeni, $rok) pokud je mám už nadefinovány do společné proměnné ($celejmeno)?


Tomášeek:
Ano, původně jsem se rozmýšlela, že bych ten rok tam nevypisovala, ale nenapadlo mě, jakým způsobem to ošetřit, neboť jsem zkoušela kombinace:
$celejmeno = str_replace('$rok', '' , $celejmeno);
$celejmeno = str_replace($rok, '' , $celejmeno);
Ani jeden způsob mi nefunguje.

Nicméně jsem přemýšlela nad tím, že by bylo user friendly, zachovat ve výpisu rok, aby uživatel věděl (v případě, že jsou v seznamu dvě totožná jména), o jakého člověka s jakým rokem se jedná.
Viz můj dotaz výše, zda lze i nějak zakomponovat str_replace pro umístění roku do závorek. Ale nejsem si jistá, zda lze nyní pracovat s proměnnými samostatně.
Keeehi
Profil
Lucyk:
Ale nejsem si jistá, zda lze nyní pracovat s proměnnými samostatně.
Nedá. Proměnná neví, jakým způsobem její obsah vznikl. Zná svůj obsah (Josef Jindra 1990) ale už neví že to vzniklo jako "$jmeno $prijmeni $rok". Řešením je, jak už psal Tomášeek to řešit už při vzniku toho obsahu. "$jmeno $prijmeni ($rok)" Pokud potřebuješ víc typů výpisu, můžeš je vytvořit do více proměnných. A nebo to neskládat do proměných předem, ale vypisovat to až na místě kde potřebuješ.
$search_output2 .= "<hr />$count results for <strong>$jmeno $prijmeni ($rok)</strong><hr />";
Lucyk
Profil
Keeehi:
Pokud bych to vypisovala až na místě, tak by mi tam vznikl 3x stejný záznam vedle sebe, tzn. Josef&Jindra&1990, neboť se na tu proměnnou ($celejmeno) odvolávám na základě query_string.

Pak mě napadá ještě spojit pouze $jmeno a $prijmeni, ale pak by mi jedno z toho nefungovalo, protože by nevěděl, kdy sloučit do jedné proměnné všechny tři, anebo pouze dvě výše uvedené.

Kód, který předchází výše uvedenému cyklu je následující:
if (isset($_SERVER['QUERY_STRING']) && !empty($_SERVER['QUERY_STRING'])){
    $prijmeni = $_SERVER['QUERY_STRING'];
    $jmeno = $_SERVER['QUERY_STRING'];
    $year = $_SERVER['QUERY_STRING'];
    $celejmeno = str_replace('&', ' ' , $_SERVER['QUERY_STRING']);
    $celejmeno = str_replace('%20', ' ' , $celejmeno);

$co = "SELECT DISTINCT * concat(jmeno,' ',prijmeni,' ',rok) FROM tabulka WHERE concat(jmeno,' ',prijmeni,' ',rok) LIKE '$celejmeno'";

Pozn. ten dotaz na výběr záznamu je jen zkrácen, zejména mi šlo o to ukázat, jakou souvislost tam má proměnná $celejmeno

Protože se v dotazu odvolávám právě na ten vybraný záznam $celejmeno, tak kdybych tam natvrdo napsala $jmeno a $prijmeni, tak nebude vědět, jaké jméno a příjmení tam má dosadit.

Maximálně mě ještě napadlo to ošetřit tím (pokud by to šlo pomocí str_replace), že mezi "mezeru a číslo 1 a 2" vložit hned za číslo 1 a 2 otevřenou závorku a nakonec proměnné vložit uzavřenou závorku.
juriad
Profil
Lucyk:
Proč si nepošleš hodnoty jednotlivými parametry „normálně“?
?jmeno=Josef&prijmeni=Jindra&rok=1980
Pak si s tím můžes dělat, co chceš.

Navíc si myslím, že je blbost pokládat ten dotaz tak, jak to děláš ty. Nesnaž se slepovat sloupce do jednoho už v databázi, ale udělej to až co nejpozději - při výpisu.
Keeehi
Profil
$prijmeni = isset($_GET['prijmeni']) ? $_GET['prijmeni'] : '';
$jmeno = isset($_GET['jmeno']) ? $_GET['jmeno'] : '';
$rok = isset($_GET['rok']) ? (int)$_GET['rok']) : 0;

$co = "SELECT DISTINCT * FROM tabulka WHERE jmeno = '".fn($jmeno)."' AND prijmeni = '".fn($prijmeni)."' and rok = $rok";

Ta funkce fn je zástupce pro nějakou escapovací funkci. Podle výše uvedeného kódu, by to v tvém případě byla mysql_real_escape_string. Takže stačí jen nahradit.
Lucyk
Profil
juriad:
Já znám jenom tento způsob zápisu, nikdy jsem nepřišla, na to, jak rozchodit ten Tvůj uvedený, Tak jsem ráda alespoň za tento. Navíc, ten dotaz do databáze mám trošku složitější v tom, že vybírám jména z tabulky, která má sloupce - jmeno1, prijmeni1, rok1, jmeno2, prijmeni2, rok2 ... proto už při výběru používám concat.

Nebo to lze nějak spojit něco v podobě
WHERE jmeno1 = '".fn($jmeno)."' AND prijmeni1 = '".fn($prijmeni)."' and rok1 = $rok";
+
WHERE jmeno2 = '".fn($jmeno)."' AND prijmeni2 = '".fn($prijmeni)."' and rok2 = $rok";


Keeehi:
Když jsem si zkusila doplnit funkci
$co = "SELECT DISTINCT * FROM tabulka WHERE jmeno = '".mysql_real_escape_string($jmeno)."' AND prijmeni = '".mysql_real_escape_string($prijmeni)."' and rok = $rok";

Tak mi vyskakuje hláška - Warning: mysql_real_escape_string() - týkající se přístupu
Tzn. že ještě je nutné ještě někam nadefinovat přístup do databáze?
T-fon
Profil
Warning je asi proto, že funkce mysql_real_escape_string je od PHP 7 zrušená. Můžeš použít mysqli_real_escape_string.
Keeehi
Profil
Lucyk:
Tak mi vyskakuje hláška - Warning: mysql_real_escape_string()
A jak přesně zní?

Spojit to samozřejmě jde
"WHERE (jmeno1 = '".fn($jmeno)."' AND prijmeni1 = '".fn($prijmeni)."' and rok1 = $rok) OR (jmeno2 = '".fn($jmeno)."' AND prijmeni2 = '".fn($prijmeni)."' and rok2 = $rok)";
Lucyk
Profil
T-fon:
Děkuji, našla jsem na internetu, že někdo používal mysql a někdo právě mysgli, tak jsem chtěla zvolit tu variantu, která se mi zdála z pohledu složitosti definice přijatelnější.

Keeehi:
Použila jsem Tebou navržený výběr a funguje to jak to má a i díky tomu jsem rozdělila původní proměnnou $celejmeno na $jmeno, $prijmeni a $rok a ty už ve výpisu upravuji dle potřeby. A i díky tomu se mi zkrátil výběrový dotaz.

Ještě bych měla dotaz týkající se diakritiky, kdy jmeno nebo prijmeni by obsahovalo např. L´ubomir.
Na internetu jsem našla, že se používá urlencode, ale netuším, kam jej zakomponovat

1. do URL (na základě kterého se spustí dotaz na výpis jména a příjmení):
echo ("<a href=\"hledani.php?jmeno=$jmeno&prijmeni=$prijmeni&rok=$rok\">$prijmeni $jmeno $rok</a>");

2. nebo do dotazu:
"WHERE jmeno = '".mysqli_real_escape_string($spojeni, $jmeno)."' AND prijmeni = '".mysqli_real_escape_string($spojeni, $prijmeni)."' and rok = $rok";

Cvičně jsem to zkoušela zaměnit ve výběru u proměnné $prijmeni, ale nefungoval výpis, kde se tato diakritika objevila. Samozřejmě tím, že jsem odstranila funkci mysqli_real_escape_string, tak ani nefunguje pro výpis, kde v proměnné je obsažena mezera.

"WHERE jmeno = '".mysqli_real_escape_string($spojeni, $jmeno)."' AND prijmeni = '".urlencode($prijmeni)."' and rok = $rok";

Jde napsat ošetření, které by se odvolávalo na to, kdyby v proměnné byla obsažena jak mezera, tak i diakritika?
juriad
Profil
Jaké kódování češtiny tvá stránka používá? (Myslím tím kódování deklarované v HTML, kódování souborů PHP, kódování v databázi.)

Urlencode nemá s diakritikou v databázi nic společného, zapomeň na něj v tomto kontextu.
1. zkontroluj, že je diakritika v databázi uložená správně - podívej se do databáze phpmyadminem, adminerem nebo jiným nástrojem. Pokud není, musí se napřed spravit.
2. pokud je diakritika v databázi správně, je potřeba pro připojení k databázi nastavit správné kódování. Některé časteji řešené dotazy pro MySQL - FAQ » MySQL a čeština
Keeehi
Profil
Lucyk:
Funkce urlencode nemá s databází nic společného. Proto tam ani nemá co dělat. Složí k zakódování speciálních znaků v url, tak aby tam mohli být a přitom adresu nerozbily. Proto to má smysl u jedničky.
echo '<a href="hledani.php?jmeno='.urlencode($jmeno).'&prijmeni='.urlencode($prijmeni).'&rok=$rok">'.htmlspecialchars("$prijmeni $jmeno $rok", ENT_QUOTES).'</a>';

Co ecapovat v jakém kontextu krásně shrnuje phpfashion.com/escapovani-definitivni-prirucka
Lucyk
Profil
juriad:
V html souboru mám kódování charset=utf-8.

V databázi mám tabulku nastavenou na utf8_czech_ci.

A když jsem zapisovala do databáze např. jméno L´ubomir, tak aby se mi na webu zobrazilo správně, tak ho mám apostrof napsaný html entitou L & # 39 bomir (samozřejmě bez těch mezer, všechno je dohromady, jen tady na foru jsem to musela upravit, jinak se mi to nezobrazovalo).

Je kódování v pořádku, nebo se používá nejčastěji jiné?

Asi bude chyba v tom, že už v databázi mám jméno uloženo s html entitou pro apostrof L & # 39 bomir?

Keeehi:
Zkusila jsem dosadit Tebou navržené řešení, nebude někde chyba (konkrétně s proměnnou &rok)? nebo při výpisu mě to odkazuje na url stránku, do které se mi nepřenesou data pro proměnnou &rok a ve výpisu je v ní obsažena 0.

Např. pro jméno Lubomir Novak to vypíše následující:
hledani.php?jmeno=Lubomir&prijmeni=Novak&rok=$rok
A vypíše mi to hlášku že nebyly nalezeny záznamy pro Lubomir Novak (0) <- v té závorce mám u echa uvedenou proměnnou &rok. Pokud do url dosadím správný věk tohoto jména, tak mi to výsledky vypíše.

A pak ještě díky tomu, že mám jméno s apostrofem uložené v databázi, tak že apostrof mám zapsán html entitou, tak už při výpisu seznamu všech jmen (ještě před tím, než vyberu konkrétní jméno pro výpis jeho záznamů) mi to nevypisuje L´ubomir, ale L & # 39 bomir.
hledani.php?jmeno=L%26%2339ubomir&prijmeni=Novak&rok=$rok (jen asi ta url nevypadá zrovna nejlíp, pokud je v ní obsaženo jméno s apostrofem).
Nicméně když toto jméno vyberu a v url zadám správný rok, tak mi to vypíše jeho záznamy (čehož jsem chtěla dosáhnout).

Možná se nabízí spíš otázka, zda mám správně nastavené kódování jazyku? Kdy všechna jména a příjmení mám bez háčků a čárek, ale u jedné nebo dvou výjimek jména se výše uvedenému apostrofu nevyhnu.
S tím, že do budoucna bych chtěla nastavit i vyhledávání podle zadaného jména, tzn. že pokud by uživatel zadal L´ubomir, aby mu toto jméno našlo, ale díky tomu, že ho mám v databázi uložené jako L & # 39 bomir, tak je asi nereálné, aby to našlo jeho záznamy?
Keeehi
Profil
Lucyk:
nebude někde chyba (konkrétně s proměnnou &rok)?
Ano, je tam chyba. Ta část s rokem by měla vypadat takto
'&rok='.$rok.'">'
Lucyk:
tak je asi nereálné, aby to našlo jeho záznamy?
Nereálné to není, ovšem jelikož by jsi to měla dělat jinak, tak to řešit nebudeš.
To jinak znamená, že v databázi máš mít data v jejich čisté formě a ne zakódovaná. Takže to tam ukládej normálně a problém nebude ;)
juriad
Profil
Lucyk:
Ukládej data do databáze nezakóvaná (neponičená). Jméno Ľubomír neobsahuje entitu, ani apostrof, ale měkké el (mäkké el).
Lucyk
Profil
Keeehi:
Děkuji, proměnná &rok už vypisuje data, která jsou v ní obsažena.

Ještě bych měla dotaz týkající se kódování stránky. Měla jsem nastaveno kódování <meta charset="utf-8"> a aby mi to vypisovalo L´ubomir, tak jsem to zadávala do tabulky v následující podobě L & # 39 bomir

V tabulce jsem nahradila u jmen html znak "& # 39" odpovídajícím znakem "´" tak, jak mi bylo doporučeno. Pak se mi ale při výpisu jména zobrazovaly následovně:


Tak jsem ještě změnila kódování na <meta charset="windows-1250"> a už se to zobrazuje jak má:


Můj dotaz zní, kdy je vhodné použít kódování utf-8 a kdy naopak windows-1250?
Keeehi
Profil
Lucyk:
kdy je vhodné použít kódování utf-8 a kdy naopak windows-1250?
Dnes prakticky vždy. Výjimkou by byly nějaké staré systémy ,ještě z dob před rozšíření utf8, které by to vyžadovaly.

U kódování je důležité, aby bylo nastaveno všude stejně. V databázi, v připojení k databázi, PHP soubor má být uložen v utf8 a i ta meta hlavička tomu musí odpovídat.
juriad
Profil
Lucyk:
Ono je možné, že jsi vložil do databáze něco jiného než apostrof (porovnej: ' a ´). Je možné, že jsi ten znak ´ dokonce vložil v kódování windows-1250, proto se v utf-8 nevykreslí správně.

Ještě jednou upozorňuji, že Ľubomir neobsahuje apostrof a pokud to jméno s apostrofem do databáze uložíš (namísto znaku Ľ), tak ti nebude správně fungovat vyhledávání bez diakritiky (protože Lubomir nesplývá s Ľubomir podle žádného collation).

Vaše odpověď


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: