Jump to content
php.lv forumi

Kā aizievietot vairākus vienādus vārdus?


shurix

Recommended Posts

  • Replies 33
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

maybe

$string ..


preg_replace("/#x/",array('a 1. elements','b 2. element'), $string);

 

maybe kaut kā tā, bet palabojiet to reg exp, man noteikti ir nepareizs

Edited by waplet
Link to comment
Share on other sites

Es gribēju izveidot datubāzes query funkciju, kas automātiski eskeipo visus padotos mainīgos. Apmēram šādi:

query("SELECT * FROM neko WHERE id = #x AND user = #x AND neko = #x", $arg1, $arg2, $arg3);

Nebūtu jāuztraucas par sql injekcijām, bet nemāku to query funkciju pareizi uztaisīt.

Link to comment
Share on other sites

Prepeared statement atbalstītājiem gribētu pajautāt, kā viņi atrisinās šādu pavisam ikdienišķu situāciju, kuru izmantojot printf un uztaisot iesūtīto argumentu tipu pārbaudi reālizētu šādi;

 

 


$ids=array(1,4,7,34,57);
$items=DB::q('SELECT * FROM items WHERE id IN (%s)',$ids)->getRows();

 

Tātad ideja ir tāda, ka q metode redz, ka $ids tips ir array, tāpēc no tā izveido stringu '1,4,7,34,57', kuru ievieto %s vietā.

Protams, ja $ids masīva elementi būtu string vērtības, nevis integer, tad attiecīgi automātiski tās eskeipotu.

Tātad gala rezultātā tiek izpildīts kverijs:

SELECT * FROM items WHERE id IN (1,4,7,34,57)

Tāpat arī $ids masīva elementu skaits var būt dažāds.

 

Risinājumi?

Edited by codez
Link to comment
Share on other sites

Nez, Man labi ar Kohana. Neterorizielalaldmemfzējiet Mani!

 

 

DB::select('money', 'cell_phone', 'candies')
->from('users')
->where('id', 'IN', $ids)
->execute()
->as_array();

 

DB::query('
SELECT `money`, `cell_phone`, `candies`
FROM `users`
WHERE `id` IN :ids
')
->param(':ids', $ids) // Nez vai shis strādā... A man vienmēr ir explode(). Es laimīgs. :)
->execute()
->as_array();

Link to comment
Share on other sites

ar implode nepietiks, pirms tam nāksies tāpat taisīt ciklu un eskeipot masīva vērtības. Bet, ja nu aizmirstās to ciklu uztaisīt? Viss itkā strādā, bet aplikācija nav injekciju droša, līdz ar to šis variants arī nav labs.

Vēl vairāk, ja masīva elementi ir stringi, tad tas jākonstruē šādi 'abc','cde', 'efg'.

Un vēl vairāk, ja taisa insertu un parametrus padod ar vienu masīvu un tie ir vienlaikus gan int, gan string tipa. Tad pat ar implode to nav iespējams apstrādāt. Bet nu labi, tas jau sen ārpus prepeared statement "filozofijas".

 

Bet par kverijuj būvēšanu izmanotjot chainingu vispār neizteikšos. Ir tādi brīnumi redzēti sastrādati, kad ar standarta chaining metodēm nav iespējams realizēt vienu vai otru vidēji sarežģitu pieprasījuma fīču.

 

Bet, daGrevi, kāpēc tad tu piebiedrojies prepeared statement ieteicējiem, ja pats tos neizmanto?

Edited by codez
Link to comment
Share on other sites

Codez, prepared statements ir tieši tas ko šīs tēmas autors meklē un mēģina uztaisīt. Jā, PDO ir ierobežojumi, piemēram, Tavs pieminētais in(), tikai tas nekādi nav iemesls, lai atteiktos no PDO un būvētu savas klases. PDO būs viennozīmīgi ātrāks par savu klasi. Izņēmuma gadījumos, ko nevar izveidot ar prepared statement, var izmantot klasisko php pieeju, izmantojot rakstzīmju virkņu apvienošanu, ko PDO pieļauj, protams tad ir jādomā par to, kā masīvs tiks sadalīts un datu drošību.

Link to comment
Share on other sites

Codez, prepared statements ir tieši tas ko šīs tēmas autors meklē un mēģina uztaisīt.

Nekādā gadījumā. Tas, ko viņš vēlas uztaisīt, ir Kverija ģenerātors, kur noteiktus simbolus aizvieto ar automātiski eskeipotām vērtībām no mainīgajiem.

Prepeared statment gadījumā nekas tamlīdzīgs (aizvietošana) pat nenotiek, jo PS notiek divās fāzēs, pa priekšu tiek aizsūtīts datubāzei prepeared statements un tikai tad dati.

 

Jā, PDO ir ierobežojumi, piemēram, Tavs pieminētais in(), tikai tas nekādi nav iemesls, lai atteiktos no PDO un būvētu savas klases. PDO būs viennozīmīgi ātrāks par savu klasi.

Ne PDO, ne prepeared statement nebūs ātrāks par mysqli vai uz tā bāzes būvētu optimālu klasi, jo:

1)pats PDO nebūs ātrāks, jo tas ir papildus abstrakcijas slānis natīvai mysql.lib funkcionalitātei.

2)PDO prepeared statement nebūs ātraks, jo prepeared statement gadījumā kverija izpilde notiek divos etapos. Pa priekšu mysql serverim tiek aizsūtīts kverijs bez datiem un uz servera tiek izstrādāts kverija izpildes plāns. Pēc tam otrajā piegājienā tiek sūtīti dati, kuri tiek ievietoti pirms tam sagatavotā kverija izpilds plānā, kamēr parastā statement gadījumā viss notiek vienā. Līdz ar to prepeared statement ir lēnāks, kā vienkārš statements.

 

Izņēmuma gadījumos, ko nevar izveidot ar prepared statement, var izmantot klasisko php pieeju, izmantojot rakstzīmju virkņu apvienošanu, ko PDO pieļauj, protams tad ir jādomā par to, kā masīvs tiks sadalīts un datu drošību.

Un kāda jēga tad izmantot PDO prepeared statements, ja?:

1)daudzos gadījumos jāmeklē visādi hacki, kas rada drošības risku. Nedomā, ka IN() ir vienīgais. Vēl pavisam populārs gadījums ir piemēram, ORDER BY lauka izvēle, kuru tu tāpāt nevari likt prepeared statmentā un tādu gadījumu ir vēl un vēl.

2)PDO prepeared statements ir lēnāki par mysqli

3)PDO PS pieraksts ir drausmīgs un nelasāms, salīdzinājumā ar optimālu izveidotu klasi, kur aizvietošana notiek ar sprintf.

 

Salīdzinājumam piemērs, kā tas būtu ar PDO PS un kā tas būtu ar labu paštaisītu db klasi uz mysqli un sprintf:

 

//PDO PS
$articles=array();
$stmt = $dbh->prepare("SELECT * FROM articles WHERE category = ? AND author= ?");
$stmt->bindParam(1, $category);
$stmt->bindParam(2, $author);
if ($stmt->execute()) {
 while ($row = $stmt->fetch()) {
$articles[]=$row;
 }
}
//un custom DB klase
$articles=$db->q("SELECT * FROM articles WHERE category=%s AND author=%s",$category,$author)->getRows();

 

Kurš ir lasāmāks?

Edited by codez
Link to comment
Share on other sites

Codez, pat ja Tu nosauc to par "vaicājumu ģeneratoru", tad lietas būtību tas nemaina. Tēmas autors grib izveidot sistēmu, kas vaicājumā padod eskeipotus parametrus. Tieši to arī prepared statement ļauj izdarīt. Tas, kā to realizē PDO un cik soļus viņš apakšā sataisa, neko nemaina, jo visumā izpildīsies vaicājums ar jau apstrādātiem parametriem.

 

PDO patiešām nebūs ātrāks par mysqli, es arī nesalīdzināju to ar mysqli, es salīdzināju PDO tieši ar paša rakstītu php klasi, kam apakšā ir eskaipošana, sprintf, rezultātu masīvu veidošana utt. Protams optimāli un ar prātu sarakstītas klases veiktspēja var būt pat izcila.

 

Es nezinu kāda jēga izmantot PDO prepared statements, jo es tos neizmantoju, ieteicu tēmas autoram tos apskatīties, jo viņš grib izveidot to, ko prepared statement ļauj izdarīt, par to vai ierobežojumi ir būtiski, tēmas autoram būs jālemj pašam.

 

Noteikti Tev radīsies jautājums kāpēc es tad vispār izmantoju PDO. To es daru, jo man viņa pilnīgi pietiek, lai aizvietotu visas tās lietas, ko agrāk, izmantojot mysql_query, es realizēju ar sevis rakstīto klasi, piemēram:

 

$db->query()
$db->query_assoc()
$db->query_row()
$db->query_value()
$db->quote()
$db->begin_tranaction()
$db->commit_transation()
$db->rollback_transaction()

 

tas tā, biežāk izmantojamās, klasei vēl nāca klāt exceptions izmantošana, kas PDO arī ir. Tātad man vienkārši nav jāveido sava php klase. Zinu ka daudzi iesaka veidot savas klases jebkurā gadījumā, jo tas ļautu vieglāk migrēt uz citām datubāzēm, piemēram, MySql->Postgre, nu nezinu, iespējams tas patiešām ir labi izmantot šādu pieeju, bet praksē vēl ne reizi neesmu ar to sastapies, tā ka nevaru spriest par šo lietu no praktiskā viedokļa puses.

 

Piemērā ko Tu iedevi nemaz nevajag izmantot ciklu, lai iegūtu rezultātu masīvu, ja izmanto PDOStatement->fetchAll, nezinu, ko Tu uzskati par nelasāmu tādā kodā, iespējams, tas ka tur ir vairāk rindiņu, ieskaitot bindParam, bet kā jau esmu teicis līdz šim citās tēmās, es neuzskatu ka papildus rindiņa, protams vajadzīga rindiņa, kodu sarežģī un padara to nelasāmu, dažreiz pat otrādāk, daudzu darbību salikšana vienā rindiņā ar dažādiem ķeburiem un saīsinājumiem, kodu padara vēl sarežģītāku.

Edited by Maris-S
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...