Autor | Zpráva | ||
---|---|---|---|
zizmun Profil |
#1 · Zasláno: 5. 9. 2023, 10:59:48
Dobrý den, rád bych vás požádal o radu. Mám script, akorát bych tam rád přidal, vyhledaní id_product v tabulce2 podle reference.
$conn = mysqli_connect($host, $user, $pass, $db); if ($conn) { echo "propojeno"; } else { die ("Tak nic"); } $affectedRow = 0; $xml = simplexml_load_file("input.xml") or die("Error: Cannot create object"); foreach ($xml->children() as $row) { $quantity = $row->quantity; $refence = $row->reference; $id_product = "SELECT id_product FROM tabulka2 WHERE reference ='$reference'"; $sql = "UPDATE tabulka1 SET quantity = '$quantity' WHERE id_product ='$id_product'"; $result = mysqli_query($conn, $sql); if (! empty($result)) { $affectedRow ++; } else { $error_message = mysqli_error($conn) . "\n"; } } |
||
Kcko Profil |
#2 · Zasláno: 5. 9. 2023, 11:16:01
na řádku 17 ti chybí prohnat ten SQL dotaz nějakou mysqli_query a následně také řádek fetchnout (mysqli_fetch_*).
Obecně je to náchylné na SQL injekce. Doporučuji použít nějakou přívětivější knihovnu na práci s MySQL např. dibiphp.com/cs |
||
zizmun Profil |
Kcko:
Takto? akorat nevim jak na mysqli_fetch_* $conn = mysqli_connect($host, $user, $pass, $db); if ($conn) { echo "propojeno"; } else { die ("Tak nic"); } $affectedRow = 0; $xml = simplexml_load_file("input.xml") or die("Error: Cannot create object"); foreach ($xml->children() as $row) { $quantity = $row->quantity; $refence = $row->reference; $vysledek = mysqli_query($conn, "SELECT id_product FROM tabulka2 WHERE reference ='$reference'"); $id_product = mysqli_fetch_array($vysledek); $sql = "UPDATE tabulka1 SET quantity = '$quantity' WHERE id_product ='$id_product'"; $result = mysqli_query($conn, $sql); if (! empty($result)) { $affectedRow ++; } else { $error_message = mysqli_error($conn) . "\n"; } } ?> |
||
Radovan789 Profil * |
#4 · Zasláno: 5. 9. 2023, 12:46:54
Řádek 19 ti teď vrátí array. Zkus si schválně dát na řádek 20 var_dump($id_product); abys viděl obsah proměnné a pak to klidně smaž.
Z toho ti vyplyne že bys měl mít na řádku 22 něco jako $id_product["id_product"] místo $id_product. |
||
anonym_ Profil * |
#5 · Zasláno: 5. 9. 2023, 12:48:46
zizmun:
„akorat nevim jak na mysqli_fetch_*“ www.php.net/manual/en/mysqli-result.fetch-array.php, atd. |
||
zizmun Profil |
Upřímně jsem ztracen, nemohl by mi někdo ukázat ten kousek kódu co je špatně, už jsem zkoušel x variant. Děkuji
$conn = mysqli_connect($host, $user, $pass, $db); if ($conn) { echo "propojeno"; } else { die ("Tak nic"); } $affectedRow = 0; $xml = simplexml_load_file("input.xml") or die("Error: Cannot create object"); foreach ($xml->children() as $row) { $quantity = $row->quantity; $refence = $row->reference; $vysledek = mysqli_query($conn, "SELECT id_product FROM tabulka2 WHERE reference ='$reference'"); $id_product = mysqli_fetch_array($vysledek); $sql = "UPDATE tabulka1_available SET quantity = '$quantity' WHERE id_product ='$id_product'"; $result = mysqli_query($conn, $sql); if (! empty($result)) { $affectedRow ++; } else { $error_message = mysqli_error($conn) . "\n"; } } ?> |
||
Keeehi Profil |
Řádek 19. Funkce
mysqli_fetch_array vrací pole které reprezentuje jeden celý řádek výsledku. I když se v dotazu ptáš jen na jeden sloupec, stále je výsledkem pole. Má sice jen jednu položku, ale stale s tím musíš pracovat jako s polem.
Ale přesně to ti psal už Radovan789 v [#4]. Ale jeho radou jsi se evidentně neřídil, i když je správně. |
||
zizmun Profil |
#8 · Zasláno: 7. 9. 2023, 14:13:49
Keeehi:
Nejsem odborník snažím se na to přijít, podle jeho rady jsem to upravil takto: $xml = simplexml_load_file("input.xml") or die("Error: Cannot create object"); foreach ($xml->children() as $row) { $quantity = $row->quantity; $refence = $row->reference; $vysledek = mysqli_query($conn, "SELECT id_product FROM tabulka2 WHERE reference ='$reference'"); $id_product = mysqli_fetch_array($vysledek); $sql = "UPDATE tabulka1_available SET quantity = '$quantity' WHERE id_product ='$id_product["id_product"]'"; $result = mysqli_query($conn, $sql); |
||
Kcko Profil |
#9 · Zasláno: 7. 9. 2023, 14:32:51
zizmun:
A nefunguje Ti teď co? vyechuj si ten $sql dotaz, zda-li dělá to co má a pak si dumpni $id_product. |
||
zizmun Profil |
Kcko:
udělal jsem to takhle a odpověď je NULL $conn = mysqli_connect($host, $user, $pass, $db); if ($conn) { echo "propojeno"; } else { die ("Tak nic"); } $affectedRow = 0; $xml = simplexml_load_file("input.xml") or die("Error: Cannot create object"); foreach ($xml->children() as $row) { $quantity = $row->quantity; $refence = $row->reference; $vysledek = mysqli_query($conn, "SELECT id_product FROM tabulka WHERE reference ='$reference'"); $id_product = mysqli_fetch_array($vysledek); var_dump($id_product); } ?> Takto vypadá xml <?xml version="1.0" encoding="UTF-8"?> <items> <item> <reference>GNTGL26</reference> <quantity>9999</quantity> </item> </items> |
||
Radovan789 Profil * |
#11 · Zasláno: 7. 9. 2023, 15:31:19
NULL znamená že SQL dotaz na řádku 18 nevrátí nic. 0 řádků z databáze. Jinými slovy v tabulce nemáš referenci podle proměnné $reference. Buď to v tabulce není nebo $row->reference je nesmysl. Schválně si zkus var_dump($row->reference); Postupným dumpováním hodnot zjistíš co je špatně.
Doufám že víš co tento script přesně dělá. Měl by upravovat hodnoty v tabulce podle XML, né přidávat nové hodnoty. |
||
zizmun Profil |
#12 · Zasláno: 8. 9. 2023, 07:04:23
Radovan789:
Ano to bych přesně chtěl, odpověď object(SimpleXMLElement)#4 (1) { [0]=> string(4) "9999" } object(SimpleXMLElement)#4 (1) { [0]=> string(7) "GNTGL26" } $xml = simplexml_load_file("input.xml") or die("Error: Cannot create object"); foreach ($xml->children() as $row) { $quantity = $row->quantity; $refence = $row->reference; } var_dump($row->quantity); var_dump($row->reference); |
||
Radovan789 Profil * |
#13 · Zasláno: 8. 9. 2023, 08:51:17
Dobře, v tuto chvíli
$row->quantity vrací object s array viz ten var_dump. Ale ty potřebuješ aby ti vrátilo jen string "9999" který následně můžeš použít ve SQL dotazu.
Takže bys to měl upravil následovně: $quantity = $row->quantity[0]; $refence = $row->reference[0]; Pak by měl předchozí kód již fungovat. |
||
Keeehi Profil |
Select fungovat bude, update z [#8] ne, tam je syntax error.
zizmun: Je správně, že už s tím pracuješ jako s polem. Nemůžeš ovšem cokoli plácnout doprostřed stringu a doufat že to bude fungovat. PHP to umí ale má to svoje pravidla. V normálním kódu je to tak, jak to máš ty. Uvnitř stringu to ale má být bez uvozovek. Tedy $id_product[id_product]
|
||
zizmun Profil |
#15 · Zasláno: 8. 9. 2023, 09:43:43
Radovan789:
Trochu jsem to změnil a vše funguje, až na to, že mám u sql napsanou špatně podmínku, kde dělám chybu? $xml = simplexml_load_file("input.xml") or die("Error: Cannot create object"); foreach ($xml->children() as $row) { $quantity = $row->quantity[0]; $reference = $row->reference[0]; $result = mysqli_query($conn, " SELECT * FROM `ps_product` WHERE reference ='$reference'"); while ($result_array = mysqli_fetch_array($result)) { echo $result_array['id_product']; } $sql = "UPDATE ps_stock_available SET quantity = '$quantity' WHERE id_product = "$result_array['id_product']""; $result = mysqli_query($conn, $sql); |
||
anonym_ Profil * |
#16 · Zasláno: 8. 9. 2023, 10:33:08
zizmun:
Já bych se být tebou naučil základy syntaxe a pořídil si editor, který ti je ukáže (když už nečteš chybové hlášky, které ti server po spustění kódu vyhazuje). Jen v tom posledním kódu v #15 je několik syntaktických chyb. |
||
zizmun Profil |
Keeehi:
Takto? $sql = "UPDATE ps_stock_available SET quantity = '$quantity' WHERE id_product = $result_array[id_product]"; anonym: Který editor? např. |
||
Radovan789 Profil * |
$sql = "UPDATE ps_stock_available SET quantity = '". $quantity ."' WHERE id_product = '". $result_array['id_product'] ."'"; Měj prosimtě na paměti že tvůj kód má bezpečnostní díry, pokud bude nahrávat XML někdo jiný tak může získat plnou moc nad celou databází (mazat, upravovat), díky SQL Injection útoku. Chtělo by to všechny hodnoty prohnat přinejmenším přes mysqli_real_escape_string nějak takhle: $sql = "UPDATE ps_stock_available SET quantity = '". mysqli_real_escape_string($quantity) ."' WHERE id_product = '". mysqli_real_escape_string($result_array['id_product']) ."'"; Sám si to uprav i v druhém SQL příkazu. zizmun: Editor například VSCode s rozšířením pro PHP. Je jednoduchý a funkční i bez základního nastavení |
||
Kcko Profil |
zizmun:
Např. Neplacený (code.visualstudio.com) (Používám já, protože nejsem jenom PHP-kař a je skvělý). Placený (www.jetbrains.com/phpstorm) (Spíše "jen" pro PHP-káře). |
||
anonym_ Profil * |
#20 · Zasláno: 8. 9. 2023, 11:07:00
Radovan789:
Ani jeden z těch tvých kódů není formálně správně (byť budou fungovat). quantity bude číslo, čili ošetření pomocí real_escape_string není správně. Navíc ta funkce má 2 parametr, ne jeden.
product_id bude pravděpodobně taktéž číslo, pak platí totéž, co výše. Může být i nečíselné (ač se to moc nedělá), pak by ošetření bylo správné (s druhým parametrem fce). |
||
Radovan789 Profil * |
#21 · Zasláno: 8. 9. 2023, 11:13:00
anonym:
To se pleteš, protože quantity a product_id je v obou případech vždy string. Quantity zadané v XML může být naprosto jakýkoliv string, takže i "' DROP TABLE ...". U product_id je to nejspíše zbytečné, ale ať to radši takovýto nováček dá naprosto všude než vůbec. ano první parametr chybí, ale to by musel doplnit i celém kódu i v query, myslím že to funguje i bez toho proto nezmiňuji. |
||
zizmun Profil |
#22 · Zasláno: 8. 9. 2023, 11:16:53
Radovan789:
mysqli_real_escape_string to chápu, upravím, posílám ještě jednou celý ten kód, protože mi to stále to pole databáze neupravuje, když ale u update vyhodím podmínku, tak to funguje, ale samozřejmě mi to přepíše všechny produkty, přitom echo mi vyhazuje správně id produktu $conn = mysqli_connect($host, $user, $pass, $db); if ($conn) { echo "propojeno"; } else { die ("Tak nic"); } $affectedRow = 0; // Load xml file else check connection $xml = simplexml_load_file("input.xml") or die("Error: Cannot create object"); foreach ($xml->children() as $row) { $quantity = $row->quantity[0]; $reference = $row->reference[0]; $result = mysqli_query($conn, " SELECT * FROM `ps_product` WHERE reference ='$reference'"); while ($result_array = mysqli_fetch_array($result)) { echo $result_array['id_product']; } $sql = "UPDATE ps_stock_available SET quantity = '". $quantity ."' WHERE id_product = '". $result_array['id_product'] ."'"; $result = mysqli_query($conn, $sql); if (! empty($result)) { $affectedRow ++; } else { $error_message = mysqli_error($conn) . "\n"; } } ?> |
||
Radovan789 Profil * |
#23 · Zasláno: 8. 9. 2023, 11:24:41
na řádku 27 si přidej echo $sql;
Vyjde ti z toho příkaz, ten příkaz si pak vlož třeba do PhpMyAdmin, jestli to napíše že to nic neovlivnilo tak buď id_product neexistuje, nebo máš jinak navrženou tabulku, například nemá sloupec quantity nebo něco takového. A while tam nepoužívej, protože očekáváš maximálně jen 1 řádek, pokud je reference zcela unikátní, takže jen: $result_array = mysqli_fetch_array($result); echo $result_array['id_product']; |
||
zizmun Profil |
#24 · Zasláno: 8. 9. 2023, 11:32:19
Radovan789:
Aha tak vyjelo to takto UPDATE ps_stock_available SET quantity = '9999' WHERE id_product = '' |
||
Radovan789 Profil * |
Když smažeš ten while tak by to snad mělo jet. Ono to totiž způsobí že po while budeš mít $result_array = NULL.
Jinak ten kód je opravdu tragický, nechci si domýšlet co ti to hodí za fatální chyby když reference nebude existovat. Spoléhám jen na to že je to low-level tool a nebudeš to nikde publikovat. Pro klid duše bys tam mohl dát podmínku navíc if (!empty($result_array)) těsně před $sql. |
||
zizmun Profil |
#26 · Zasláno: 8. 9. 2023, 11:49:39
Radovan789:
Podmínku jsem přidal a funguje to. Děkuji všem, aspoň jsem se něco přiučil, jste borci. |
||
anonym_ Profil * |
#27 · Zasláno: 8. 9. 2023, 12:44:10
Radovan789:
„To se pleteš, protože quantity a product_id je v obou případech vždy string. Quantity zadané v XML může být naprosto jakýkoliv string, takže i "' DROP TABLE ...". U product_id je to nejspíše zbytečné, ale ať to radši takovýto nováček dá naprosto všude než vůbec.“ Ano, vstup je string, ale v DB je (mělo by být) na 99% číslo. Ošetření se provádí podle typu v DB, nikoliv podle vstupu. Ke zbytku se vyjadřovat nebudu, nemám na to sílu. |
||
Andrej.B Profil |
#28 · Zasláno: 8. 9. 2023, 13:08:44
Zaregistruj sa u GPTchat, vysvetli ti vsetko co budes potrebovat a napise vzorovy kod. Budes to mat takto lepsie ako sa pytat na kazdu osobitnu vec tu. A velmi rychlo.
Aj ked tu ludia su ochotny vzdy dobre poradit a hlavne pri databazovych otazkach urobit neskutocne dobru pomoc. |
||
Časová prodleva: 24 dní
|
0