Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

PDO Hvordan tester man for tomt recordset?

4 views
Skip to first unread message

J�rn Andersen

unread,
Jan 13, 2013, 12:24:12 PM1/13/13
to
Hej,

P� opfordring af Leif Neland (27 Dec 2012 11:12:21) er jeg ved at
pr�ve at l�re, hvordan PDO fungerer.

Men hvad er den "rigtige" m�de at checke for tomt recordset?

Med ADO plejer jeg bare at:
if ($rs->EOF) {
// tomt recordset
} else {
// g�r noget
}

Men n�r jeg s�ger p�, hvordan man g�r i PDO, synes jeg svarene virker
lidt "vage".

Enten foresl�s at lave en "SELECT COUNT(Id) ..." f�rst og s� bagefter
lave den rigtige foresp�rgsel (samme WHERE-betingelser).

Eller der foresl�s at hente data ud i et array og s� checke p�:
count($array) == 0.

Begge metoder virker ikke "rigtige" p� mig, og jeg har en fornemmelse
af, at der m� v�re en mere enkel metode - ??

Mvh. J�rn

--
J�rn Andersen
http://socialister.dk
http://marxisme.dk

Martin

unread,
Jan 14, 2013, 6:49:36 AM1/14/13
to
On 13-01-2013 18:24, Jørn Andersen wrote:
> Hej,
>
> På opfordring af Leif Neland (27 Dec 2012 11:12:21) er jeg ved at
> prøve at lære, hvordan PDO fungerer.
>
> Men hvad er den "rigtige" måde at checke for tomt recordset?
>
> Med ADO plejer jeg bare at:
> if ($rs->EOF) {
> // tomt recordset
> } else {
> // gør noget
> }
>
> Men når jeg søger på, hvordan man gør i PDO, synes jeg svarene virker
> lidt "vage".
>
> Enten foreslås at lave en "SELECT COUNT(Id) ..." først og så bagefter
> lave den rigtige forespørgsel (samme WHERE-betingelser).
>
> Eller der foreslås at hente data ud i et array og så checke på:
> count($array) == 0.
>
> Begge metoder virker ikke "rigtige" på mig, og jeg har en fornemmelse
> af, at der må være en mere enkel metode - ??
>
> Mvh. Jørn
>


$statement = $dbh->prepare('SELECT FROM fruit');
$statement->execute();
$count = $statement->rowCount();
if ($count > 0) {
while( $row = $Statement->fetch() ) {
}
} else {
// No rows
}

Anders Wegge Keller

unread,
Jan 14, 2013, 6:55:29 AM1/14/13
to
Martin <martinprikaarhofsnabelagmailprikcom> writes:

> $statement = $dbh->prepare('SELECT FROM fruit');
> $statement->execute();
> $count = $statement->rowCount();
> if ($count > 0) {
> while( $row = $Statement->fetch() ) {
> }
> } else {
> // No rows
> }

rowCount() er ikke garanteret at returnere noget meningsfuldt efter
en select:

If the last SQL statement executed by the associated PDOStatement
was a SELECT statement, some databases may return the number of
rows returned by that statement. However, this behaviour is not
guaranteed for all databases and should not be relied on for
portable applications.

<http://php.net/manual/en/pdostatement.rowcount.php>


--
/Wegge

Leder efter redundant peering af dk.*,linux.debian.*

J�rn Andersen

unread,
Jan 14, 2013, 2:31:12 PM1/14/13
to
On 14 Jan 2013 12:55:29 +0100, Anders Wegge Keller <we...@wegge.dk>
wrote:
Den faldt jeg nemlig ogs� over - og selv om jeg ikke n�dvendigvis
beh�ver at have s�rligt "portabel" kode, s� vil man jo heller ikke
*bevidst* g�re det besv�rligt for sig selv (eller andre) om 2 �r fx.

Men hvad er s� den rigtige m�de?

Anders Wegge Keller

unread,
Jan 14, 2013, 2:41:19 PM1/14/13
to
Jørn Andersen <jo...@jorna.dk> writes:

> On 14 Jan 2013 12:55:29 +0100, Anders Wegge Keller <we...@wegge.dk>
> wrote:
>
> >Martin <martinprikaarhofsnabelagmailprikcom> writes:
> >
> >> $statement = $dbh->prepare('SELECT FROM fruit');
> >> $statement->execute();
> >> $count = $statement->rowCount();
> >> if ($count > 0) {
> >> while( $row = $Statement->fetch() ) {
> >> }
> >> } else {
> >> // No rows
> >> }
> >
> > rowCount() er ikke garanteret at returnere noget meningsfuldt efter
> >en select:
> >
> > If the last SQL statement executed by the associated PDOStatement
> > was a SELECT statement, some databases may return the number of
> > rows returned by that statement. However, this behaviour is not
> > guaranteed for all databases and should not be relied on for
> > portable applications.
> >
> ><http://php.net/manual/en/pdostatement.rowcount.php>
>
> Den faldt jeg nemlig også over - og selv om jeg ikke nødvendigvis
> behøver at have særligt "portabel" kode, så vil man jo heller ikke
> *bevidst* gøre det besværligt for sig selv (eller andre) om 2 år fx.

Det er nemlig det. MySQL-PDO-connectoren har ændret sig på det punkt
på et tidspunkt.

> Men hvad er så den rigtige måde?

Hvis det er vigtigt for dig på forhånd at vide hvor mange rows du
får, er der nok ikke anden udvej end at starte med en "SELECT COUNT(*)
WHERE <<dine conditions>>".

Personligt ville jeg forsøge at undgå at være afhængig af den
viden. I mit professionelle virke[1] har jeg aldrig haft brug for at
vide hvor mange records jeg får tilbage, når jeg laver et opslag. Men
dit behov kan selvfølgelig godt være et andet.

1. Nu er maskinel sortering af flybaggage og pakkepost, nok heller
ikke det område der er nærmest beslægtet med ting man ville kode i
php, så YMMV.

Leif Neland

unread,
Jan 14, 2013, 3:27:28 PM1/14/13
to
Jᅵrn Andersen forklarede den 14-01-2013:
> On 14 Jan 2013 12:55:29 +0100, Anders Wegge Keller <we...@wegge.dk>
> wrote:
>> rowCount() er ikke garanteret at returnere noget meningsfuldt efter
>> en select:
>>
>> If the last SQL statement executed by the associated PDOStatement
>> was a SELECT statement, some databases may return the number of
>> rows returned by that statement. However, this behaviour is not
>> guaranteed for all databases and should not be relied on for
>> portable applications.
>>
>> <http://php.net/manual/en/pdostatement.rowcount.php>

f.ex. mssql returnerer ikke rowcount ved select.
>
> Den faldt jeg nemlig ogsᅵ over - og selv om jeg ikke nᅵdvendigvis
> behᅵver at have sᅵrligt "portabel" kode, sᅵ vil man jo heller ikke
> *bevidst* gᅵre det besvᅵrligt for sig selv (eller andre) om 2 ᅵr fx.
>
> Men hvad er sᅵ den rigtige mᅵde?
>
Hvis man er sikker pᅵ, at man ikke fᅵr returneret et stort antal rᅵkker
og/eller mange store felter, kan man hente alle data pᅵ een gang ind i
et array med fetchall eller lignende.

Sᅵ er antallet af rᅵkker i resultatet jo lig antallet af rᅵkker i
arrayet.

Det kan samtidig vᅵre hurtigere, at der ikke skal laves kald til
databasen for hver rᅵkke (her ser jeg bort fra evt buffering i php).

Leif

--
Husk kᅵrelys bagpᅵ, hvis din bilfabrikant har taget den idiotiske
beslutning at undlade det.


Arne Vajhøj

unread,
Jan 14, 2013, 10:06:08 PM1/14/13
to
On 1/13/2013 12:24 PM, J�rn Andersen wrote:
> P� opfordring af Leif Neland (27 Dec 2012 11:12:21) er jeg ved at
> pr�ve at l�re, hvordan PDO fungerer.
>
> Men hvad er den "rigtige" m�de at checke for tomt recordset?
>
> Med ADO plejer jeg bare at:
> if ($rs->EOF) {
> // tomt recordset
> } else {
> // g�r noget
> }
>
> Men n�r jeg s�ger p�, hvordan man g�r i PDO, synes jeg svarene virker
> lidt "vage".
>
> Enten foresl�s at lave en "SELECT COUNT(Id) ..." f�rst og s� bagefter
> lave den rigtige foresp�rgsel (samme WHERE-betingelser).
>
> Eller der foresl�s at hente data ud i et array og s� checke p�:
> count($array) == 0.
>
> Begge metoder virker ikke "rigtige" p� mig, og jeg har en fornemmelse
> af, at der m� v�re en mere enkel metode - ??

Det mest ekvivalente er vel:

$stmt->execute();
if($row = $stmt->fetch()) {
// g�r noget
} else {
// tomt recordset
}

Arne


J�rn Andersen

unread,
Jan 14, 2013, 10:30:54 PM1/14/13
to
On 14 Jan 2013 20:41:19 +0100, Anders Wegge Keller <we...@wegge.dk>
wrote:

> Hvis det er vigtigt for dig p� forh�nd at vide hvor mange rows du
>f�r, er der nok ikke anden udvej end at starte med en "SELECT COUNT(*)
>WHERE <<dine conditions>>".

Nej, ikke om der er 7 eller 50, men om der er 0 eller nogen.

Men jeg tror, jeg vil checke Arnes svar - det ser umidelbart ud til at
v�re det, jeg skal bruge.

J�rn Andersen

unread,
Jan 14, 2013, 10:31:35 PM1/14/13
to
On Mon, 14 Jan 2013 22:06:08 -0500, Arne Vajh�j <ar...@vajhoej.dk>
wrote:

>Det mest ekvivalente er vel:
>
>$stmt->execute();
>if($row = $stmt->fetch()) {
> // g�r noget
>} else {
> // tomt recordset
>}

Tak, den vil jeg checke.

Stig Johansen

unread,
Jan 15, 2013, 2:47:51 AM1/15/13
to
Anders Wegge Keller wrote:

> Hvis det er vigtigt for dig på forhånd at vide hvor mange rows du
> får, er der nok ikke anden udvej end at starte med en "SELECT COUNT(*)
> WHERE <<dine conditions>>".

Den er faktisk heller ikke 'god nok'.
Antag en database hvor der findes een record med en givenm værdi, og
følgende tidslinie for bruger 1 og 2:
1) Bruger1: select count(*) from tabel where id=42 - resulatt = 1
2) Bruger2: delete from tabel where id=42
3) Bruger1 tror nu der er 1, men det er der ikke længere.

>
> Personligt ville jeg forsøge at undgå at være afhængig af den
> viden. I mit professionelle virke[1] har jeg aldrig haft brug for at
> vide hvor mange records jeg får tilbage, når jeg laver et opslag. Men
> dit behov kan selvfølgelig godt være et andet.

Af samme årsag som ovenfor *ved* databasen ikke hvoer mange records der er
føre hele resultsættet er hentet.

De 'implementeringer' der returnerer rowcount henter hele skidtet før der er
en angivelse af antallet.

Det kan væree særdeles problematisk i et flerbruger miljø, da man risikerer
'agressive locking scheme', og i sidste ende deadlocks.

> 1. Nu er maskinel sortering af flybaggage og pakkepost, nok heller
> ikke det område der er nærmest beslægtet med ting man ville kode i
> php, så YMMV.

Enig - PHP er kun til 'hobbykodning'.

--
Med venlig hilsen
Stig Johansen

Martin

unread,
Jan 15, 2013, 3:46:47 AM1/15/13
to
On 15-01-2013 08:47, Stig Johansen wrote:
> Enig - PHP er kun til 'hobbykodning'.

Hvor hulen har du det fra?
S� det vil sige du mener at facebook og twitter kun er hobbykodning -
det er sku ikke dit bedste statement...

Anders Wegge Keller

unread,
Jan 15, 2013, 6:10:02 AM1/15/13
to
Martin <martinprikaarhofsnabelagmailprikcom> writes:

> On 15-01-2013 08:47, Stig Johansen wrote:
> > Enig - PHP er kun til 'hobbykodning'.
>
> Hvor hulen har du det fra?
> Så det vil sige du mener at facebook og twitter kun er hobbykodning -
> det er sku ikke dit bedste statement...

Facebook bruger hiphop, så det er så som så med at det er php.

<http://en.wikipedia.org/wiki/HipHop_for_PHP>

Martin

unread,
Jan 15, 2013, 6:19:32 AM1/15/13
to
On 15-01-2013 12:10, Anders Wegge Keller wrote:
> Martin <martinprikaarhofsnabelagmailprikcom> writes:
>
>> On 15-01-2013 08:47, Stig Johansen wrote:
>>> Enig - PHP er kun til 'hobbykodning'.
>>
>> Hvor hulen har du det fra?
>> Så det vil sige du mener at facebook og twitter kun er hobbykodning -
>> det er sku ikke dit bedste statement...
>
> Facebook bruger hiphop, så det er så som så med at det er php.
>
> <http://en.wikipedia.org/wiki/HipHop_for_PHP>
>

I know, men HipHop er nu også bare oversætter til C++, som laver en php
extension ud af din PHP kode.

Dvs. at din PHP kode bliver læst direkte ind i PHP, ganske som date,
gdlib, xdebug og zend extension er udvidelser skrevet i C++ til PHP.

Problemet med extensions er at de skal opdateres hver gang PHP springer
en version, og skal så recompiles til PHP.

Ganske som extensions lavet af HipHop også skal recompiles hver gang PHP
får et nyt versions nummer.

Martin

unread,
Jan 15, 2013, 6:23:37 AM1/15/13
to
og ja, så kan man også sagtens køre wordpress som hiphop extension, hvis
man skulle få lyst til det.

Bare husk laver man en ændring i en af PHP filerne, så skal der
recompiles igen.

Så facebook er stadigvæk PHP, da PHP sourcen stadigvæk er der (dog
selvfølgelig kun i deres udviklings miljø, og recompiles så til en
hiphop extension når udviklingsmiljøet er klar til produktion)

Også derfor at ikke alle ændringer i den amerikanske facebook version
når Danmark først, fordi at hiphop extensionen ikke bliver kastet på
alle servere på samme tid

Arne Vajhøj

unread,
Jan 15, 2013, 9:42:12 PM1/15/13
to
On 1/14/2013 2:41 PM, Anders Wegge Keller wrote:
> Hvis det er vigtigt for dig på forhånd at vide hvor mange rows du
> får, er der nok ikke anden udvej end at starte med en "SELECT COUNT(*)
> WHERE <<dine conditions>>".

Bemærk at det kun er sikkert ved transaction isolation level
serializable, hvilket koster.

Arne


Arne Vajhøj

unread,
Jan 15, 2013, 9:48:22 PM1/15/13
to
On 1/15/2013 2:47 AM, Stig Johansen wrote:
> Anders Wegge Keller wrote:
>> Hvis det er vigtigt for dig p� forh�nd at vide hvor mange rows du
>> f�r, er der nok ikke anden udvej end at starte med en "SELECT COUNT(*)
>> WHERE <<dine conditions>>".
>
> Den er faktisk heller ikke 'god nok'.
> Antag en database hvor der findes een record med en givenm v�rdi, og
> f�lgende tidslinie for bruger 1 og 2:
> 1) Bruger1: select count(*) from tabel where id=42 - resulatt = 1
> 2) Bruger2: delete from tabel where id=42
> 3) Bruger1 tror nu der er 1, men det er der ikke l�ngere.

Hvilket foruds�tter at der ikke er brugt transaction isolation
level serializable.

>> Personligt ville jeg fors�ge at undg� at v�re afh�ngig af den
>> viden. I mit professionelle virke[1] har jeg aldrig haft brug for at
>> vide hvor mange records jeg f�r tilbage, n�r jeg laver et opslag. Men
>> dit behov kan selvf�lgelig godt v�re et andet.
>
> Af samme �rsag som ovenfor *ved* databasen ikke hvoer mange records der er
> f�re hele results�ttet er hentet.
>
> De 'implementeringer' der returnerer rowcount henter hele skidtet f�r der er
> en angivelse af antallet.
>
> Det kan v�ree s�rdeles problematisk i et flerbruger milj�, da man risikerer
> 'agressive locking scheme', og i sidste ende deadlocks.

Afh�nger af transaction isolation level og om der bruges locking
eller MVCC.

Men derudover er pointen vel lidt s�gt, fordi i de fleste tilf�lde
vil alle r�kker som query returnerer vel blive hentet alligevel.

Grunden til at det ikke er en god l�sning er nok snarere
problemet med data s� store at de ikke kan gemmes i
memory.

Arne


Arne Vajhøj

unread,
Jan 15, 2013, 9:51:22 PM1/15/13
to
Twitter bruger vel ikke PHP. De bar kendt for at bruge RoR, men
er skiftet til noget custom Java.

Men FaceBook, Yahoo og Wikipedia bruger PHP og det er nok
de f�rreste som har behov for mere end dem.

Arne


Arne Vajhøj

unread,
Jan 15, 2013, 9:55:02 PM1/15/13
to
On 1/15/2013 6:10 AM, Anders Wegge Keller wrote:
> Martin <martinprikaarhofsnabelagmailprikcom> writes:
>> On 15-01-2013 08:47, Stig Johansen wrote:
>>> Enig - PHP er kun til 'hobbykodning'.
>>
>> Hvor hulen har du det fra?
>> Så det vil sige du mener at facebook og twitter kun er hobbykodning -
>> det er sku ikke dit bedste statement...
>
> Facebook bruger hiphop, så det er så som så med at det er php.
>
> <http://en.wikipedia.org/wiki/HipHop_for_PHP>

Udviklerne skriver stadig PHP kode.

Og jeg vil mene at hip hops eksistens ikke er udtryk for
at FB ser problemer med normal brug af PHP men snarere at
FB er så glade for PHP at de vil bruge det til kode som
normalt ville blive skrevet i native extensions.

Arne


Stig Johansen

unread,
Jan 16, 2013, 2:16:42 AM1/16/13
to
Facebook (og andre scriptsprog) overlever kun pga effektiv caching:
https://www.varnish-software.com/use-case/facebook-united-states

Nu snakkede jeg om virkelige multiuser systemer, og ikke caching hvor data
er - eller kan v�re - for�ldet.

Stig Johansen

unread,
Jan 16, 2013, 2:22:19 AM1/16/13
to
Arne Vajh�j wrote:

> Hvilket foruds�tter at der ikke er brugt transaction isolation
> level serializable.

Lagde du m�rke til problemstillingen om locks?
http://www.canaimasoft.com/f90sql/OnlineManual/Chapter05/Serializable
isolation level.htm

Der er forskel p� 'enkeltbrugersystemer' og 'multibrugersystemer'.

J�rn Andersen

unread,
Jan 16, 2013, 3:30:03 AM1/16/13
to
On Wed, 16 Jan 2013 08:16:42 +0100, Stig Johansen <wop...@gmail.com>
wrote:

>Facebook (og andre scriptsprog) overlever kun pga effektiv caching:
>https://www.varnish-software.com/use-case/facebook-united-states
>
>Nu snakkede jeg om virkelige multiuser systemer, og ikke caching hvor data
>er - eller kan v�re - for�ldet.

De to ting beh�ver ikke st� i mods�tning til hinanden ;-)
P� facebook er det notorisk sv�rt at f� cachede billeder til at
forsvinde, selv om de forl�ngst ikke eksisterer eller er erstattet af
andre.

Arne Vajhøj

unread,
Jan 20, 2013, 10:58:26 PM1/20/13
to
On 1/16/2013 2:16 AM, Stig Johansen wrote:
> Martin <martinprikaarhofsnabelagmailprikcom> wrote:
>
>> On 15-01-2013 08:47, Stig Johansen wrote:
>>> Enig - PHP er kun til 'hobbykodning'.
>>
>> Hvor hulen har du det fra?
>> Så det vil sige du mener at facebook og twitter kun er hobbykodning -
>> det er sku ikke dit bedste statement...
>
> Facebook (og andre scriptsprog) overlever kun pga effektiv caching:
> https://www.varnish-software.com/use-case/facebook-united-states

Alle sites i mega størrelse a la FB cacher voldsomt i alle tiers. Det
er nødvendigt.

Varnish og konkurrerende produkter bruges også af Java EE og ASP.NET
web sites.

FB's brug af PHP kan med HipHop vel ikke længere kaldes for
brug af script sprog.

Så det link understøtter ligesom ikke dit postulat.

Arne

Arne Vajhøj

unread,
Jan 20, 2013, 11:06:43 PM1/20/13
to
On 1/16/2013 2:22 AM, Stig Johansen wrote:
> Arne Vajhøj wrote:
>> Hvilket forudsætter at der ikke er brugt transaction isolation
>> level serializable.
>
> Lagde du mærke til problemstillingen om locks?
> http://www.canaimasoft.com/f90sql/OnlineManual/Chapter05/Serializable
> isolation level.htm

For det første ændrer det ikke på hvad jeg skrev. Med transaction
isolation level serializable var der ikke noget samtidigheds problem.

For det andet så er det du linker til heller ikke korrekt. Transaction
isolation level serializable kræver ikke locks - det kræver enten locks
eller brug af MVCC.

> Der er forskel på 'enkeltbrugersystemer' og 'multibrugersystemer'.

Ja.

Men da du snakker om samtidigheds problem og jeg snakker
om transaction isolation level, så antager vi vel begge at
det er et multibrugersystem.

Jeg tror iøvrigt at det er ret sjældent at man laver
enkeltbrugersystemer i PHP.

Arne


Stig Johansen

unread,
Jan 21, 2013, 2:14:54 AM1/21/13
to
Arne Vajh�j wrote:

> On 1/16/2013 2:22 AM, Stig Johansen wrote:
>
>> Der er forskel p� 'enkeltbrugersystemer' og 'multibrugersystemer'.
>
> Ja.
>
> Men da du snakker om samtidigheds problem og jeg snakker
> om transaction isolation level, s� antager vi vel begge at
> det er et multibrugersystem.

Vi er ude i flueknepperi.

Hvis man serialisererer sine transaktioner, i en hvilken som helst layer, er
det i min optik 'enkeltbrugersystem', da ikke 2 har adgang samtidig.

Jeg snakker om svartidsproblemer og ikke konflikter i forhold til
opdateringer.

Derfor brugte jeg citationstegn.
0 new messages