MySQL Limit: Anzahl Ergebnisse ohne LIMIT herausfinden

In einigen Situation ist der geneigte Entwickler interessiert an der Gesamtzahl der Ergebnisse, die eine Abfrage ohne LIMIT – Klausel ergeben hätte. Die Holzhammermethode in so einem Fall ist, die Abfrage einfach nochmal ohne LIMIT abzufeuern. Doch es geht besser. Und zwar mit folgendem Konstrukt:

1
2
3
4
5
6
SELECT SQL_CALC_FOUND_ROWS productid, price, stock
FROM products
WHERE price > 100
LIMIT 10, 30;

SELECT FOUND_ROWS();

Durch das “Einschleusen” von SQL_CALC_FOUND_ROWS können wir direkt danach mit FOUND_ROWS() die Gesamtzahl an Ergebnissen erfragen. Für den Fall, dass nur ein Attribut selektiert werden soll, kann man auch direkt eine Abfrage draus machen:

1
2
3
4
5
6
SELECT SQL_CALC_FOUND_ROWS productid
FROM products
WHERE price > 100
LIMIT 10, 30
UNION
SELECT FOUND_ROWS();

Auf die Art und Weise wird an das Resultset als letzte Zeile noch die Gesamtzahl an Ergebnissen ohne LIMIT angehangen. Mehr dazu direkt im MySQL Manual.

Veröffentlicht unter Datenbanken, Quicktips, webdev | 9 Kommentare

Parallel processing in PHP

Since PHP does not offer native threads, we have to get creative to do parallel processing. I will introduce 3 fundamentally different concepts to emulate multithreading as good as possible.

Using systemcalls

If you have some basic linux knowledge, you will know that a background process can be started by adding ampersand to the systemcall (in Windows, it’s the start-command)

1
2
dav@david:/var/www$ php index.php &
[1] 3229

The PHP script is running silently in the background. What is being printed to the shell (3229) is the process id, so that we are able to kill the process using

Veröffentlicht unter Linux, Performance, php, webdev | 13 Kommentare

PHP WTF #6

Heute inkrementieren wir mal Strings.

1
2
3
4
5
6
$string = 'Iteration number 0';

$i = 10;

while ($i--)
    echo $string++ . "<br />";

Output:

1
2
3
4
5
6
7
8
9
10
Iteration number 0
Iteration number 1
Iteration number 2
Iteration number 3
Iteration number 4
Iteration number 5
Iteration number 6
Iteration number 7
Iteration number 8
Iteration number 9

Das war ja schonmal ganz nett zum warmwerden. Aber jetzt: fasten your seatbelts.

1
2
3
4
for ($i = 'a'; $i <= 'z'; $i++)
{
    echo $i . " ";
}

Output:

1
a b c d e f g h i j k l m n o p q r s t u v w x y z aa ab ac ad ae af ag ah ai aj ak al am an ao ap aq ar as at au av aw ax ay az ba bb bc bd be bf bg bh bi bj bk bl bm bn bo bp bq br bs bt bu bv bw bx by bz ca cb cc cd ce cf cg ch ci cj ck cl cm cn co cp cq cr cs ct cu cv cw cx cy cz da db dc dd de df dg dh di dj dk dl dm dn do dp dq dr ds dt du dv dw dx dy dz ea eb ec ed ee ef eg eh ei ej ek el em en eo ep eq er es et eu ev ew ex ey ez fa fb fc fd fe ff fg fh fi fj fk fl fm fn fo fp fq fr fs ft fu fv fw fx fy fz ga gb gc gd ge gf gg gh gi gj gk gl gm gn go gp gq gr gs gt gu gv gw gx gy gz ha hb hc hd he hf hg hh hi hj hk hl hm hn ho hp hq hr hs ht hu hv hw hx hy hz ia ib ic id ie if ig ih ii ij ik il im in io ip iq ir is it iu iv iw ix iy iz ja jb jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc kd ke kf kg kh ki kj kk kl km kn ko kp kq kr ks kt ku kv kw kx ky kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt lu lv lw lx ly lz ma mb mc md me mf mg mh mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on oo op oq or os ot ou ov ow ox oy oz pa pb pc pd pe pf pg ph pi pj pk pl pm pn po pp pq pr ps pt pu pv pw px py pz qa qb qc qd qe qf qg qh qi qj qk ql qm qn qo qp qq qr qs qt qu qv qw qx qy qz ra rb rc rd re rf rg rh ri rj rk rl rm rn ro rp rq rr rs rt ru rv rw rx ry rz sa sb sc sd se sf sg sh si sj sk sl sm sn so sp sq sr ss st su sv sw sx sy sz ta tb tc td te tf tg th ti tj tk tl tm tn to tp tq tr ts tt tu tv tw tx ty tz ua ub uc ud ue uf ug uh ui uj uk ul um un uo up uq ur us ut uu uv uw ux uy uz va vb vc vd ve vf vg vh vi vj vk vl vm vn vo vp vq vr vs vt vu vv vw vx vy vz wa wb wc wd we wf wg wh wi wj wk wl wm wn wo wp wq wr ws wt wu wv ww wx wy wz xa xb xc xd xe xf xg xh xi xj xk xl xm xn xo xp xq xr xs xt xu xv xw xx xy xz ya yb yc yd ye yf yg yh yi yj yk yl ym yn yo yp yq yr ys yt yu yv yw yx yy yz

Wow! Und allemal cooler als der hier:

1
2
3
4
for ($i = ord('a'); $i <= ord('z'); $i++)
{
    echo chr($i) . " ";
}

Output:

1
a b c d e f g h i j k l m n o p q r s t u v w x y z

Wem langweilig ist, kann damit gern ein bisschen rumspielen (ASCII-Tabelle gefällig?). Siehe dazu auch den Manual-Eintrag bei php.net:

PHP follows Perl’s convention when dealing with arithmetic operations on character variables and not C’s. For example, in Perl ‘Z’+1 turns into ‘AA’, while in C ‘Z’+1 turns into ‘[‘ ( ord(‘Z’) == 90, ord(‘[‘) == 91 ). Note that character variables can be incremented but not decremented and even so only plain ASCII characters (a-z and A-Z) are supported.

Veröffentlicht unter php, PHP-WTF, webdev | 3 Kommentare

Hashverfahren und Sicherheit

Es gehört mittlerweile zum guten Ton, auf md5 herumzuhacken. Dabei fällt immer wieder das Argument, dass in md5 Kollisionen entdeckt wurden. Eine Kollision bedeutet, dass zwei unterschiedliche Strings zum gleichen Hash führen. Dies muss zwangsläufig bei allen Hashverfahren der Fall sein, denn eine Abbildung von viel Text auf wenig Text wird naturgemäß irgendwann eine Überschneidung bei zwei verschiedenen Inputs ergeben. Ein gutes Hashverfahren kommt also mit weniger Kollisionen daher als ein schlechtes.

Zum selbst testen (Unterschiede im Input sind mit einem Ausrufezeichen vermerkt):

Veröffentlicht unter php, Security, webdev | 15 Kommentare

Webtesting mit SimpleTest – Selenium light

SimpleTest führt neben dem übermächtigen PHPUnit ein Schattendasein in der PHP-Community. Vielleicht nicht ganz zu Unrecht, schließlich kommt es mit deutlich weniger Features daher. Eher durch Zufall entdeckte ich beim Durchstöbern der Dokumentation das verdammt coole Webtesting Feature – zwar nicht so mächtig wie Selenium (das ja u.a. einen echten Browser fernsteuern kann), aber für kleine Checks durchaus gut zu gebrauchen. Aber der Reihe nach.

SimpleTest installieren

Die aktuelle Alpha-Version 1.1 herunterladen. Zusätzlich noch das File arguments.php direkt aus dem SVN herunterladen und ins simpletest-Verzeichnis stecken. Das wurde anscheinend in der alpha vergessen und führt sonst zu einem Fehler.

Veröffentlicht unter php, Quicktips, webdev | 2 Kommentare

Best-of-the-Web 7

Und erneut gibt es Link-Spaß für die ganze Familie.

Veröffentlicht unter Javascript, php, Software Engineering, webdev | Hinterlasse einen Kommentar

Javascript: Arrays kopieren

Banale Aufgabe: Erstelle eine unabhängige Kopie von einem Javascript-Array. Was erstmal billig klingt entpuppt sich für unwissende, PHP verwöhnte Entwickler doch als tricky.

1
2
3
4
5
6
7
var colors = ["red", "blue", "green"];
var copied = colors;

copied[0] = "magenta";

console.log(colors); //["magenta", "blue", "green"]
console.log(copied); //["magenta", "blue", "green"]

In diesem Beispiel sehen wir also, dass die vermeintliche Kopie eigentlich das gleiche Element ist. Gleiches gilt entsprechend für das Übergeben eines Arrays als Parmeter an eine Funktion.

1
2
3
4
5
6
7
8
9
var colors = ["red", "blue", "green"];

test(colors);
console.log(colors); //["magenta", "blue", "green"]

function test(arr)
{
    arr[0] = "magenta";
}

Offensichtlich nicht wie von PHP gewohnt By Value sondern By Reference.

Ja und wie geht es nun?

Enter Array.slice. Damit lassen sich wirkliche Kopien erstellen.

1
2
3
4
5
6
7
var colors = ["red", "blue", "green"];
var colorscopy = colors.slice(); //or colors.slice(0, colors.length);

colorscopy[0] = "magenta";

console.log(colors); //["red", "blue", "green"]
console.log(colorscopy); //["magenta", "blue", "green"]

Tada! Als Alternative könnte man sich auch selbst was zusammenbasteln, etwa so:

Veröffentlicht unter Javascript, webdev | 5 Kommentare

Reingefallen: Wie man sich auf Facebook “Likes” erschleicht

Ich dachte eigentlich, immun gegen so billige Spielchen zu sein. Aus dem “Ich weiß schon, wo ich hinklicke”-Grund hatte ich auch lange Zeit keinen Virenscanner drauf und fuhr eigentlich immer gut. Gestern hat michs jedoch erwischt – auf Facebook. Also jetzt nicht so richtig erwischt, aber ich habe ein Video geliked, ohne es zu wollen. Erbost ging ich der Sache auf den Grund und war ziemlich schockiert über diese miese Praktik. Aber der Reihe nach.

Veröffentlicht unter Javascript, misc IT, Persönlich | 78 Kommentare

Dealing with Trusted Timestamps in PHP (RFC 3161)

This article won’t be pariculary interesting for the most readers. My aim is to help the billions of developers that are confused about dealing with trusted timestamping. If you don’t know what Trusted Timestamps are, carry on.

Explanation of the concept behind Trusted Timestamps

I can’t put it better as Wikipedia (Trusted timestamping) does:

Trusted timestamping is the process of securely keeping track of the creation and modification time of a document. Security here means that no one — not even the owner of the document — should be able to change it once it has been recorded provided that the timestamper’s integrity is never compromised.

Veröffentlicht unter php, Security, webdev | 6 Kommentare

PHP WTF #5

…oder: Bei magischen Funktionen gut aufpassen.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class TestingEmpty
{
    public function __get($var)
    {
        if ($var == "test_empty")
            return "Hi there!";
    }
}

$t = new TestingEmpty();
echo $t->test_empty; //Hi there!
var_dump(strlen($t->test_empty)); //int(9)
var_dump(empty($t->test_empty)); //bool(true)
$externalvar = $t->test_empty;
var_dump(empty($externalvar)); //bool(false)

Aha, also empty, aber mit String-Length von 9 Zeichen. Nach dem Zuweisen zu einer “wirklichen” Variable dann auch nicht mehr empty.

Zur Abwechslung wollen wir aber nicht nur meckern, sondern noch konstruktiv zeigen, wie man diesen WTF (der vielleicht garkeiner ist?) behebt:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class TestingEmpty
{
    public function __get($var)
    {
        if ($var == "test_empty")
            return "Hi there!";
    }
   
    public function __isset($var)
    {
        echo "__isset triggered";
       
        if ($var == "test_empty")
            return true;
       
        return false;
    }
}

$t = new TestingEmpty();
echo $t->test_empty; //Hi there!
var_dump(strlen($t->test_empty)); //int(9)
//__isset triggered
var_dump(empty($t->test_empty)); //bool(false)... endlich

Durchs Überschreiben der magischen Funktion __isset, die implizit von empty bei __get aufgerufen wird, können wir das Verhalten so korrigieren, wie es uns gefällt.

Auch wenn man das nicht als “Bug” bezeichnen kann und das Verhalten genau betrachtet auch logisch ist, wäre es trotzdem schön wenn darauf im Manual zu empty besser hingewiesen werden würde.

Veröffentlicht unter php, PHP-WTF, webdev | 9 Kommentare