Variabele uit function wordt niet herkend

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Pagina: 1 2 volgende »

Bas van de Ven

Bas van de Ven

12/05/2015 09:25:21
Quote Anchor link
Het aantal records uit een query wil ik weten en stop ik in de variabele $aantMeld. Direct na het submitten moet deze variabele opnieuw worden bepaald. Nu kan ik de query nogmaals schrijven na if (isset($_POST['knpMeld_'])) echter schrijf ik twee keer dezelfde code. Daarom wil ik de query in een function() stoppen, zie hieronder. Als ik de functie opvraag wordt de variabele $aantMeld in mijn code na het aanroepen niet herkend. Notice: Undefined variable: aantMeld in ... . Wat is hiervan de reden ?

<code>
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
<?php
function aantal_melden() {
include "connect_db.php";
$lidId = $_SESSION["I1"];
$aantalmelden = mysqli_query($db,"SELECT * FROM vw_Meldingen
                        WHERE lidId = "
.mysqli_real_escape_string($db,$lidId)." and isnull(dmmeld) and code = 'DOO' and skip <> 1") or die (mysqli_error($db));
    $aantMeld = mysqli_num_rows($aantalmelden);
}

aantal_melden();

echo $aantMeld;  /* Deze wordt niet herkend */ ?>

</code>
 
PHP hulp

PHP hulp

26/04/2024 20:12:03
 
- SanThe -

- SanThe -

12/05/2015 09:35:39
Quote Anchor link
Variabelen die in een function worden aangemaakt zijn buiten de function onbekend. In jouw geval is een return waarin de waarde staat het simpelst.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
<?php
function aantal_melden() {
include "connect_db.php";
$lidId = $_SESSION["I1"];
$aantalmelden = mysqli_query($db,"SELECT * FROM vw_Meldingen
                        WHERE lidId = "
.mysqli_real_escape_string($db,$lidId)." and isnull(dmmeld) and code = 'DOO' and skip <> 1") or die (mysqli_error($db));
    return mysqli_num_rows($aantalmelden);
}


echo aantal_melden();
?>
 
Henk de Vriep

Henk de Vriep

12/05/2015 09:36:52
Quote Anchor link
Edit: SanThe was me te snel af!
Gewijzigd op 12/05/2015 09:38:46 door Henk de Vriep
 
Bas van de Ven

Bas van de Ven

12/05/2015 09:57:37
Quote Anchor link
Thanks
 
Thomas van den Heuvel

Thomas van den Heuvel

12/05/2015 13:41:49
Quote Anchor link
Waarom vraag je alle data op als je enkel het aantal records wilt hebben? Gebruik COUNT().
 
Bas van de Ven

Bas van de Ven

12/05/2015 20:31:39
Quote Anchor link
Ik heb altijd count() gebruikt. Daarbij moet ik het aantal records met een while loop ophalen.
De functie mysqli_num_rows() is minder code, vandaar.
Wel overweeg ik soms 1 veld (bijv. het Id) uit een tabel op te halen. Dus select Id from ... ipv select * from ... i.c.m. mysqli_num_rows()
O.b.v. wat ik her en der lees ben ik in de veronderstelling dat select * from ... beter is voor de performance. Als het om 1 veld gaat en dan ook een geindexeerd veld als Id, is mijn theorie nog steeds dat select Id from ... sneller is. Proefondervindelijk wil ik dit zelf vaststellen.
 
Eddy E

Eddy E

12/05/2015 20:42:38
Quote Anchor link
Het lijkt mij dat een simpele COUNT veel sneller is dan 1000 dingen ophalen en die stuk voor stuk gaan tellen.
Immers, of MYSQL zelf intern telt en 1 getal (1000) doorgeeft of 1000 nummers die PHP gaat tellen...
 
Frank Nietbelangrijk

Frank Nietbelangrijk

12/05/2015 21:06:28
Quote Anchor link
ook een include in een functie is niet zo heel erg netjes over het algemeen.
De while waarover je spreekt kun je vervangen door een if omdat een SELECT COUNT(*) FROM tablename maximaal één record terug zal geven. Zoals Thomas en Eddy je al duidelijk aangeven: ga niet alle rijen ophalen om enkel het aantal records te tellen.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
function aantal_melden($db, $lidId)
{

    $result = mysqli_query($db,"SELECT COUNT(*) as aantal FROM vw_Meldingen
                        WHERE lidId = "
.mysqli_real_escape_string($db,$lidId)." and isnull(dmmeld) and code = 'DOO' and skip <> 1") or die (mysqli_error($db));

    if($row = mysqli_fetch_assoc($result))
            return $row['aantal'];

    return FALSE;
}


include "connect_db.php";

echo aantal_melden($db, $_SESSION["I1"]);
?>
Gewijzigd op 13/05/2015 21:29:32 door Frank Nietbelangrijk
 
Bas van de Ven

Bas van de Ven

12/05/2015 21:13:49
Quote Anchor link
Mijn database heb ik opnieuw ingericht (meerdere databases samengevoegd) en in dezelfde tijd heb ik veel Count() functies vervangen door Mysqli_num_rows. Lokaal merkte ik niets maar online is de site een stuk trager geworden na mijn herinrichting. Mogelijk ligt het aan de count() functies i.p.v. het samenvoegen van meerdere databases. Ik zal dit eens gaan bekijken.
 
Eddy E

Eddy E

12/05/2015 21:20:10
Quote Anchor link
Even een kleine benchmark gedaan:
Bij 1000x!

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
PHP telt rijen: 9226 rijen. Dat duurde: 0.01322350692749 sec gemiddeld
mySQL telt rijen: 9226 rijen. Dat duurde: 0.0002274329662323 sec gemiddeld


Dat is een slordige... 58.14 keer zo snel!!!

Met deze code:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<?php


    // start script hier
    error_reporting(E_ALL);

    $mysqli = new mysqli('localhost', $dbuser, $dbpasswd, $dbname);
    if ($mysqli -> connect_errno)
    {

        printf("Connect failed: %s\n", $mysqli -> connect_error);
    }


    // start hier
    $before = microtime(true);

    for ($i = 0; $i < 1000; $i++)
    {

        $query = "SELECT topic_id FROM phpbb_topics";
        if ($result = $mysqli -> query($query))
        {

            $iets = mysqli_num_rows($result);
            $result -> free();
        }
    }


    $after = microtime(true);
    echo 'PHP telt rijen: ' . $iets . ' rijen. Dat duurde: ' . ($after - $before) / $i . " sec gemiddeld<br>";

    // start hier deel 2
    $before2 = microtime(true);

    for ($i = 0; $i < 1000; $i++)
    {

        $res = mysqli_query($mysqli, "SELECT COUNT(topic_id) AS aantal FROM phpbb_topics");
        while ($row = $result -> fetch_assoc())
        {

            $iets = $row['aantal'];
        }

        $result -> free();
    }


    $after2 = microtime(true);
    echo 'mySQL telt rijen: ' . $iets . ' rijen. Dat duurde: ' . ($after2 - $before2) / $i . " sec gemiddeld<br>";
?>
Gewijzigd op 12/05/2015 21:21:02 door Eddy E
 
Thomas van den Heuvel

Thomas van den Heuvel

12/05/2015 22:46:41
Quote Anchor link
Los van het feit dat het langzamer is vreet het ook nog eens een brok geheugen, omdat je resultset ergens (zij het tijdelijk) opgeslagen moet worden... Dus zelfs al is het "snel" ben je onnodig resources aan het verstoken.

Daarnaast vergeet je even gemakshalve dat je in je uppie aan het testen bent. Stel nu dat er 10 bezoekers min of meer tegelijkertijd je site bekijken en daarbij bovengenoemde SELECT * queries worden uitgevoerd. Het kan dan zijn dat je op een bepaald moment een enorme dip in je beschikbare geheugen hebt of op enig moment je gewoon geheugen tekort komt, waardoor queries gaan wachten etc. Dit is een effect wat zichzelf versterkt. Deze constructie is dus alles behalve schaalbaar.

Dus los van "snelheid" zou je eens wat geheugen benchmarks kunnen doen. Daarbij moet gezegd worden dat je in PHP alleen een reëel beeld krijgt van geheugenconsumptie van MySQL als je de MySQL native driver gebruikt, omdat deze "aan de PHP kant" al haar MySQL zaken doet, en daarmee wordt dus ook geheugengebruik op 1 plaats geteld (en daarbij schijnt de native driver ook gewoon een stuk efficiënter te zijn). Als je geen native driver gebruikt kun je volgens mij aan de PHP zijde geen objectieve informatie krijgen over MySQL geheugengebruik.

Meer over MySQL native driver
Gewijzigd op 12/05/2015 22:48:03 door Thomas van den Heuvel
 
Ger van Steenderen
Tutorial mod

Ger van Steenderen

13/05/2015 17:57:05
Quote Anchor link
Ter aanvulling:

Let op dat er een belangrijk verschil is tussen COUNT(*)/COUNT(1) en COUNT(kolomnaam).
COUNT(*) en COUNT(1) tellen alle rijen, COUNT(kolomnaam) telt alleen de rijen waarin 'kolomnaam' niet leeg is.
 
Johan de wit

johan de wit

13/05/2015 18:03:33
Quote Anchor link
Eddy E op 12/05/2015 21:20:10:
Even een kleine benchmark gedaan:
Bij 1000x!

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
PHP telt rijen: 9226 rijen. Dat duurde: 0.01322350692749 sec gemiddeld
mySQL telt rijen: 9226 rijen. Dat duurde: 0.0002274329662323 sec gemiddeld


Dat is een slordige... 58.14 keer zo snel!!!

Met deze code:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<?php


    // start script hier
    error_reporting(E_ALL);

    $mysqli = new mysqli('localhost', $dbuser, $dbpasswd, $dbname);
    if ($mysqli -> connect_errno)
    {

        printf("Connect failed: %s\n", $mysqli -> connect_error);
    }


    // start hier
    $before = microtime(true);

    for ($i = 0; $i < 1000; $i++)
    {

        $query = "SELECT topic_id FROM phpbb_topics";
        if ($result = $mysqli -> query($query))
        {

            $iets = mysqli_num_rows($result);
            $result -> free();
        }
    }


    $after = microtime(true);
    echo 'PHP telt rijen: ' . $iets . ' rijen. Dat duurde: ' . ($after - $before) / $i . " sec gemiddeld<br>";

    // start hier deel 2
    $before2 = microtime(true);

    for ($i = 0; $i < 1000; $i++)
    {

        $res = mysqli_query($mysqli, "SELECT COUNT(topic_id) AS aantal FROM phpbb_topics");
        while ($row = $result -> fetch_assoc())
        {

            $iets = $row['aantal'];
        }

        $result -> free();
    }


    $after2 = microtime(true);
    echo 'mySQL telt rijen: ' . $iets . ' rijen. Dat duurde: ' . ($after2 - $before2) / $i . " sec gemiddeld<br>";
?>


En als je bedragen hebt?
 
Frank Nietbelangrijk

Frank Nietbelangrijk

13/05/2015 18:32:25
Quote Anchor link
Johan de wit op 13/05/2015 18:03:33:
En als je bedragen hebt?


Doe eens een gok?

Ik doe dan ook een ultieme poging...

Wat Jij doet Johan is het volgende:
Jij haalt alle dozen van zolder helemaal naar beneden (twee trappen af) en gaat dan de inhoud bekijken (of tellen). Daarna Breng je alle dozen die je niet nodig hebt weer naar zolder (twee trappen op).

Wat wij voorstellen om te doen is:
Op de zolder zelf te zoeken en slechts één doos mee naar beneden te nemen.
 
Johan de wit

johan de wit

13/05/2015 18:46:45
Quote Anchor link
Je vat verkeert. Wat ik er mee bedoelde is moet bedragen ook op het zelfde manier aangepakt worden?
 
Frank Nietbelangrijk

Frank Nietbelangrijk

13/05/2015 18:50:36
Quote Anchor link
Dit is hoe je moet denken:

Ik mot alleen dat van die mysql server hebben wat ik echt mot weten en de rest mag ie houden ;-)

Ja, SQL kent prima methodes om getallen/bedragen op te tellen alsmede het gemiddelde uit te rekenen of de laagste of hoogste waarde te vinden.
 
- Ariën  -
Beheerder

- Ariën -

13/05/2015 18:51:56
Quote Anchor link
We hebben het nu over het tellen van records in een database. Of het nou honden, katten, auto's of prijzen zijn wat er in staat maakt helemaal niets uit.
 
Johan de wit

johan de wit

13/05/2015 19:16:14
Quote Anchor link
Oke, dank je wel @Frank en @Aar
 
Bas van de Ven

Bas van de Ven

13/05/2015 21:26:47
Quote Anchor link
Wat doet return FALSE; binnen function() in de post van Frank ? Als ik die verwijder merk ik geen verschil.
 
Ivo P

Ivo P

13/05/2015 21:34:12
Quote Anchor link
mocht de query mislukken (tabel blijkt niet te bestaan, database is even de benen strekken, etc)

dan lukt de fetch niet, en kom je dus niet bij de return $row['aantal']

dan treedt de Return FALSE op.
 
Frank Nietbelangrijk

Frank Nietbelangrijk

13/05/2015 21:34:13
Quote Anchor link
er stond een ; te veel. ik heb die nu verwijderd.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
<?php
function aantal_melden($a)
{

    if($a == 1)
            return TRUE;

    return FALSE;
}

?>


Als $a gelijk is aan 1 dan wordt de functie verlaten en TRUE teruggegeven. Als $a NIET gelijk is aan 1 dan wordt de regel met return TRUE overgeslagen en wordt de code in de functie vervolgt. De eerste regel die dan uitgevoerd wordt is return FALSE. Nu wordt de functie wederom verlaten maar wordt er FALSE mee teruggegeven.

Het is eigenlijk hetzelfde als dit:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
<?php
function aantal_melden($a)
{

    if($a == 1)
        return TRUE;
    else
        return FALSE;
}

?>



Toevoeging op 13/05/2015 21:47:11:

Je zou dit kunnen doen:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
function aantal_melden($db, $lidId)
{

    $result = mysqli_query($db,"SELECT COUNT(*) as aantal FROM vw_Meldingen
                        WHERE lidId = "
.mysqli_real_escape_string($db,$lidId)." and isnull(dmmeld) and code = 'DOO' and skip <> 1") or die (mysqli_error($db));

    if($row = mysqli_fetch_assoc($result))
            return $row['aantal'];

    return FALSE;
}


include "connect_db.php";

$meldingen = aantal_melden($db, $_SESSION["I1"]);
if($meldingen === FALSE)
    echo 'Er is iets fout gegaan. aantal_melden() geeft FALSE terug';
else if($meldingen == 0)
    echo 'Er zijn geen meldingen gevonden.';
else if($meldingen == 1)
    echo 'Er is één melding gevonden.';
else
    echo 'Er zijn '.$meldingen.' meldingen gevonden.';
?>


Let hierbij goed op de === (drie stuks dus).
Bij een == (twee stuks) is een cijfer 0 hetzelfde als FALSE.
 

Pagina: 1 2 volgende »



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.