Avatar billede flashnoob Nybegynder
13. august 2005 - 00:05 Der er 18 kommentarer og
1 løsning

Nogen der kan forklare denne kode? (2d array)

Hejsa.
Jeg har fundet den kode der står længere nede på http://dk2.php.net/manual/da/function.mysql-fetch-array.php#52806 . Er der nogen der kan forklare koden for mig, vil nemlig gerne bruge koden til mit databasekald, da det vist vil blive en smule lettere... :)

================Koden=============

<?
  class mysql_resultset
  {
  var $results, $map;

  function mysql_resultset($results)
  {
    $this->results = $results;
    $this->map = array();

    $index = 0;
    while ($column = mysql_fetch_field($results))
    {
      $this->map[$index++] = array($column->table, $column->name);
    }
  }

  function fetch()
  {
    if ($row = mysql_fetch_row($this->results))
    {
      $drow = array();

      foreach ($row as $index => $field)
      {
        list($table, $column) = $this->map[$index];
        $drow[$table][$column] = $row[$index];
      }

      return $drow;
    }
    else
      return false;
  }
  }
?>

The class is initialized with a mysql_query result:

<?
  $resultset = new mysql_resultset(mysql_query($sql));
?>

The constructor builds an array that maps each field index to a ($table, $column) array so we can use mysql_fetch_row and access field values by index in the fetch() method. This method then uses the map to build up the 2d-array.

An example:

<?
  $sql =
  "select orders.*, clients.*, productos.* ".
  "from orders, clients, products ".
  "where join conditions";

  $resultset = new mysql_resultset(mysql_query($sql));

  while ($drow = $resultset->fetch())
  {
  echo 'No.: '.$drow['orders']['number'].'<br>';
  echo 'Client: '.$drow['clients']['name'].'<br>';
  echo 'Product: '.$drow['products']['name'].'<br>';
  }
?>
 

Dét jeg ikke forstår ved koden, og som nok også er grunden til at jeg ikke kan får den til at virke er dette her:

$sql =
  "select orders.*, clients.*, productos.* ".
  "from orders, clients, products ".
  "where join conditions";

Den første "order" er da en colum ik'? og hvorfor er der .* efter? Er det fordi den skal hente det hele fra tabellerne Order, clients og productos???  Det er vel det samme som at skrive $sql = "select orders from orders where ..." `(hvis det nu kun var orders der skulle hentes fra ik'?)

Hvis det nu er det samme som $sql = "select orders from orders where ..."  så kan jeg ikke forstå det her echo 'No.: '.$drow['orders']['number'].'<br>'; (Hvad er number?)

Håber der er en der ude der vil svare på alle mine spørgsmål :D
Avatar billede nielle Nybegynder
13. august 2005 - 00:32 #1
FROM-delen:

... FROM orders, clients, products ...

- angiver at der udtrækkes data fra 3 tabeller, "orders", "clients" og "products".

Normalt når man gør dette, i modsætning når man kun har een tabel i sin SELECT, så vil der kunne column-navne som går igen i to eller flere af tabellerne. Så hvis man f.eks. skriver:

SELECT id FROM tabel1, tabel2 ...

- og id optræder i begge, så vil der nu pludselig kunne opstå tvivl om hvilket ID det drejer sig om.

Derfor angiver man så tabelnavnet sammen med column-navnet:

SELECT tabel2.id FROM tabel1, tabel2 ...

- for at afklare denne tvivl.

Det er netop det der sker iden angivne SELECT. Dog har de en variation på denne:

SELECT orders.*, clients.*, productos.* FROM orders, clients, products ...

- og her betyder "orders.*" altså bare "alle felterne i tabellen orders". Hvis man kun havde en tabel, orders, i samme SELECT ville det se sådan ud:

SELECT * FROM orders ...
Avatar billede nielle Nybegynder
13. august 2005 - 00:35 #2
Somme tider vil man, i stedet for at bruge selve tabel-navnene, bruge aliaser sådan at:

SELECT orders.*, clients.*, productos.* FROM orders, clients, products ...

- kunne se sådan her ud:

SELECT o.*, c.*, p.* FROM orders AS o, clients AS c, products AS ...

Aliaser kan gør, ellers meget lange og uoverskuelige, SQL-sætninger mere korte og simple.
Avatar billede flashnoob Nybegynder
13. august 2005 - 00:42 #3
Okay... det gav lidt mere mening..:) men hvad så med:

echo 'No.: '.$drow['orders']['number'].'<br>';

Jeg forstår ikke lige hvad 'number' er i denne sammenhæng?
Avatar billede nielle Nybegynder
13. august 2005 - 00:47 #4
Det skyldes den metode som drow hentes med

while ($drow = $resultset->fetch())

Da SQL'en udtrækker rækker hvori der ligger colums for alle de 3 tabeller, så er det smart at man kan adskille dem:

$drow['orders']['number']

- referere simpelthen til den column som hedder "number" og som kom fra "orders" tabellen.
Avatar billede flashnoob Nybegynder
13. august 2005 - 01:08 #5
$sql =
  "select level_id(en række).*, weight(en række).* ".
  "from level(en tabel), measurement(en tabel) ".
  "where person_id=1";

  $resultset = new mysql_resultset(mysql_query($sql));

  while ($drow = $resultset->fetch())
  {
  echo 'Level: '.$drow['level']['level_id'].'<br>';
  echo 'Weight: '.$drow['measurement']['weight'].'<br>';

  }
 
  }

Hvis jeg så har en tabel der hedder Level, med en række der hedder level_id og personen med id=1 har 2 i level_id, vil den så vise det?
og den neden under... vil vise personen med id=1  's weight?

eller er jeg helt på vildspor :)
Avatar billede nielle Nybegynder
13. august 2005 - 08:46 #6
Næste korrekt, du har fået lavet din SQL lidt forkert. Syntaksen er:

SELECT dinTabel1.ditFelt1, dinTabel2.diteFelt2 FROM dinTabel1, dinTabel2 ...

- men hvor man altså kan have *  i stedet for feltet.

Din SQL skulle derfor være:

$sql =
    "select level.level_id, measurement.weight ".
    "from level, measurement ".
    "where person_id=1";

- eller:

$sql =
    "select level.*, measurement.* ".
    "from level, measurement ".
    "where person_id=1";

Nå du ved hvilke felter du skal bruge i det efterfølgende, bør du altid nøjes med at udtrække disse i stedetfor at bruge den meget brede *-notation som tager alt.
Avatar billede nielle Nybegynder
13. august 2005 - 08:54 #7
Der er noget andet som lige bør siges. Det lyder som om at det er første gang at du tænker på at kombinere to eller flere tabeller i et SQL-udtryk, og det er den ”join conditions” der også omtales.

Hvis du har en database over personer, så kunne vi forestille os at du havde en tabel med deres levels, og en med deres meaurements. I dette tilfælde kunne man finde på at udtrække efter denne:

SELECT level.*, measurement.* FROM level, measuement

Dette ville være forkert idet at det ville give os alle kombinationer af alle personers levels, og alle personers measurements – også selv om disse kommer for forskellige personer (det kaldes for det ”cartesiske produkt”).

Det er her join-betingelsen kommer ind. Vi vil jo kun have de kombinationer som tilhøre den samme person:

SELECT level.*, measurement.* FROM level, measuement WHERE  level.person_id= measuement.person_id

Dette kaldes for en join, og deraf ”join betingelse”.
Avatar billede flashnoob Nybegynder
13. august 2005 - 13:42 #8
Aha... det gav lidt mere forståelse. Og det er rigtigt, det med at hente to eller flere ting ud af databasen på én gang er helt nyt for mig. Men tror at det vil gøre arbejdet med min kode og databasen meget lettere. :)

Jeg kan dog stadig ikke få det til at virke. Jeg vil trække personen med id=1 's 'name' ud fra tabellen 'person' og personens 'weight' ud fra tabellen 'measurements'.

Min kode ser nu sådan her ud:
Avatar billede flashnoob Nybegynder
13. august 2005 - 13:44 #9
ups:

$person_id = 1;
$sql =
    "select person.*, measurement.* ".
    "from person, measurement ".
    "where level.person_id=measurement.person_id";


  $resultset = new mysql_resultset(mysql_query($sql));

  while ($drow = $resultset->fetch())
  {
  echo 'Name: '.$drow['person']['name'].'<br>';
  echo 'Weight: '.$drow['measurement']['weight'].'<br>';

  }


Jeg ved ikke mht. $person_id ... er den rigtig angivet eller er det heelt forkert?

Den fejl jeg får når jeg kører koden er:

Warning: mysql_fetch_field(): supplied argument is not a valid MySQL result resource in ****\includes\not used\class.php on line 12

Warning: mysql_fetch_row(): supplied argument is not a valid MySQL result resource in ****\includes\not used\class.php on line 20
Avatar billede nielle Nybegynder
13. august 2005 - 14:18 #10
Prøv lige at fjerne det der "new" fra starten af:

new mysql_resultset(mysql_query($sql));
Avatar billede flashnoob Nybegynder
13. august 2005 - 14:26 #11
Hmm.. så kommer denne fejl:
Fatal error: Call to undefined function: mysql_resultset() in c:\appserv\www\training_site\index.php on line 34

linie 34 ser nu sådan her ud:  $resultset = mysql_resultset(mysql_query($sql));
Avatar billede nielle Nybegynder
13. august 2005 - 14:59 #12
Korrekt, mysql_resultset, er heller ikke en standard PHP funktion. I de kode eksempler der er på den side du angav, er der derimod nogen som definere hvordan den skal se ud:

<?
class mysql_resultset
{
    var $results, $map;

    function mysql_resultset($results)
    {
        $this->results = $results;
        $this->map = array();

        $index = 0;
        while ($column = mysql_fetch_field($results))
        {
            $this->map[$index++] = array($column->table, $column->name);
        }
    }

    function fetch()
    {
        if ($row = mysql_fetch_row($this->results))
        {
            $drow = array();

            foreach ($row as $index => $field)
            {
                list($table, $column) = $this->map[$index];
                $drow[$table][$column] = $row[$index];
            }

            return $drow;
        }
    else
        return false;
    }
}
?>

- og hvis du tilføjer denne stump kode, så skal der faktisk stp new der hvor du lige har fjernet det.
Avatar billede flashnoob Nybegynder
13. august 2005 - 15:05 #13
Den class har jeg defineret længere oppe i mit dokument. Du får lige det hele :)

<?
class mysql_resultset
{
    var $results, $map;

    function mysql_resultset($results)
    {
        $this->results = $results;
        $this->map = array();

        $index = 0;
        while ($column = mysql_fetch_field($results))
        {
            $this->map[$index++] = array($column->table, $column->name);
        }
    }

    function fetch()
    {
        if ($row = mysql_fetch_row($this->results))
        {
            $drow = array();

            foreach ($row as $index => $field)
            {
                list($table, $column) = $this->map[$index];
                $drow[$table][$column] = $row[$index];
            }

            return $drow;
        }
    else
        return false;
    }
}
?>

<?php

$person_id = "1";

$sql =
    "select person.*, measurement.* ".
    "from person, measurement ".
    "where level.person_id=measurement.person_id";


  $resultset = new mysql_resultset(mysql_query($sql));

  while ($drow = $resultset->fetch())
  {
  echo 'Name: '.$drow['person']['name'].'<br>';
  echo 'Weight: '.$drow['measurement']['weight'].'<br>';

  }
?>

Men jeg får stadig samme fejl som jeg beskrev tidligere :/ (Vil gerne lige takke for din hjælp indtil nu :) )
Avatar billede flashnoob Nybegynder
13. august 2005 - 15:08 #14
I den join betingelse du beskrev tidligere: where level.person_id=measurement.person_id

Er det så rigtigt, det jeg gør, med at definere person_id, blot ved at $person_id="1"; før jeg definerer $sql ?
Avatar billede nielle Nybegynder
13. august 2005 - 15:26 #15
Det eksempel jeg gav er til tilfældet hvor du vil have alle personer ud via et SQL-kald. Hvis du kun vil have en person ud - den person du kender som $person_id=1 - så bør SQL-sætningen i stedet se sådan her ud:

$sql = "SELECT level.*, measurement.* FROM level, measuement WHERE level.person_id=measuement.person_id AND level.person_id=" . $person_id;

- eller, hvad der kan komme ud på det samme i dette tilfælde:

$sql = "SELECT level.*, measurement.* FROM level, measuement WHERE level.person_id=". $person_id . " AND measuement.person_id=" . $person_id;

(men så kaldes det bare ikke mere en join).
Avatar billede flashnoob Nybegynder
13. august 2005 - 15:37 #16
Øv... jeg får stadig samme fejlmeddelelse:

Warning: mysql_fetch_field(): supplied argument is not a valid MySQL result resource in ****\includes\not used\class.php on line 12

Warning: mysql_fetch_row(): supplied argument is not a valid MySQL result resource in ****\includes\not used\class.php on line 20

Linie 12 er: while ($column = mysql_fetch_field($results))

Linie 20 er: if ($row = mysql_fetch_row($this->results))

i class mysql_resultset

... hvordan kan det være?
Avatar billede nielle Nybegynder
13. august 2005 - 15:45 #17
Præv at rette din linje:

$resultset = new mysql_resultset(mysql_query($sql));

- til noget i stim med:

$result = mysql_query($sql) or die(mysql_error());
$resultset = new mysql_resultset($result);

Hvis der er en fejl i din $sql skulle dette gerne blive meget mere tydeligt nu.
Avatar billede flashnoob Nybegynder
13. august 2005 - 16:09 #18
JA!!!! Det virkede! Perfekt. 1000 tak for afklaringen nielle. Læg et svar så får du  point som du ærligt har fortjent. :)
Avatar billede nielle Nybegynder
13. august 2005 - 16:16 #19
Svar :^)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester