Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I am building a system, mostly for consolidating learning but will be used in practice.

I will try and verbally explain the part of the E-R diagram I am focusing on:

Each cadet can have many uniformID's

Each Uniform ID is a new entry in table uniform, so cadets (table) may look like:

id | name    | ... | uniformID

1  | Example | ... | 1,2,3

uniform table:

id | notes             | cadet

1  | Need new blahh    | 1

2  | Some stuff needed | 1

3  | Whatever you like | 1

On second thought, looks like I wont need that third column in the db.

I am trying to iterate through each id in uniformID, code:

<?php
$cadet = $_GET['id']; // set  from URL

$query = mysql_query("SELECT `uniformID` FROM `cadets` 
  WHERE id = '$cadet' LIMIT 1") 
  or die(mysql_error()); // get uniform needed as string

// store it
while ($row = mysql_fetch_array($query)) {
  $uniformArray = $row['uniformID']; 
}
echo $uniformArray . "  ";
$exploded = explode(",", $uniformArray); // convert into an array

// for each key in the array perform a new query
foreach ($exploded as $key => $value) {
  $query(count($exploded));
  $query[$key] = mysql_query("SELECT * FROM `uniform` WHERE `id` = '$value'");
}

?>

As I say, this is mainly for consolidation purposes but I have come up with a error, sql is saying:

Fatal error: Function name must be a string in C:\wamp\www\intranet\uniform.php on line 82

line 82 is:

$query[$key] = mysql_query("SELECT * FROM `uniform` WHERE `id` = '$value'");

I wasn't sure it would work so I tried it and now i'm stuck!

EDIT:

Thanks to everyone who has contributed to this! This is now the working code:

foreach ($exploded as $key => $value) {
              //$query(count($exploded));
              $query = mysql_query("SELECT * FROM `uniform` WHERE `id` = '$value'");
              while ($row = mysql_fetch_array($query)) {
                echo "<tr>
                  <td>" . $row['id'] . "</td>
                  <td>" . $row['note'] . "</td>
                </tr>";
              }
            }

Added the while and did the iteration by nesting it in the foreach

share|improve this question
You have weird quotes around uniform and id, is that a coincidence? – Liam Spencer Nov 8 '12 at 10:22
2  
The error is here $query(count($exploded));. Line 81. – air4x Nov 8 '12 at 10:25
1  
There is no need to specify the size of an array beforehand in php. – air4x Nov 8 '12 at 10:26
2  
At the top you have assigned the result of mysql_query, which is a resource, to $query. Rename that variable. – air4x Nov 8 '12 at 10:29
1  
@air4x Good point. PHP's typing is usually so silent we forget about it. – npfedwards Nov 8 '12 at 10:33
show 13 more commentsadd comment (requires an account with 50 reputation)

1 Answer

up vote 1 down vote accepted

In addition to your tables

cadets(id, ...)
uniforms(id, ...)

use a cross-product table that describes the relation between entities of cadets and entities of uniforms

cadets_x_uniforms(cadet_id, uniform_id)

For each relationship (in this case cadet x has uniform y) put a record with the respective ids into the cross-product table.

... hm, a working example will do better in this case I suppose...

<?php
$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'localonly', 'localonly');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
setup($pdo);

// fetch the uniforms of a specific cadet
$stmt = $pdo->prepare('
    SELECT
        c.name,u.id,u.labelid
    FROM
        so_cadets as c
    LEFT JOIN
        so_cadet_uniform as cxu
    ON
        c.id=cxu.cadet_id
    LEFT JOIN
        so_uniforms as u
    ON
        cxu.uniform_id=u.id
    WHERE
        c.name=?
');
$stmt->execute( array('cadetB') );
$stmt->setFetchMode(PDO::FETCH_ASSOC);
echo "uniforms of cadetB\n";
foreach( $stmt as $row ){
    echo join(', ', $row), "\n";
}

// fetch cadets without uniforms
$query = '
    SELECT
        c.name
    FROM
        so_cadets as c
    WHERE
        NOT EXISTS(SELECT uniform_id FROM so_cadet_uniform as cxu WHERE c.id=cxu.cadet_id)
';
echo "cadets without uniforms\n";
foreach( $pdo->query($query, PDO::FETCH_ASSOC) as $row ){
    echo join(', ', $row), "\n";
}   


function setup($pdo) {
    $pdo->exec('
        CREATE TEMPORARY TABLE so_cadets (
            id int auto_increment,
            name varchar(32),
            primary key(id)
        )
    ');

    $pdo->exec('
        CREATE TEMPORARY TABLE so_uniforms (
            id int auto_increment,
            labelid varchar(32),
            primary key(id),
            unique key(labelid)
        )
    ');

    $pdo->exec('
        CREATE TEMPORARY TABLE so_cadet_uniform (
            cadet_id int,
            uniform_id int,
            primary key(cadet_id,uniform_id)
        )
    ');


    $stmt = $pdo->prepare('INSERT INTO so_cadets (name) VALUES (?)');
    foreach( range('A','F') as $c ) {
        $stmt->execute( array('cadet'.$c));
    }

    $stmt = $pdo->prepare('INSERT INTO so_uniforms (labelid) VALUES (?)');
    foreach( range('K','Z') as $c ) {
        $stmt->execute( array('label'.$c));
    }

    $stmt = $pdo->prepare('INSERT INTO so_cadet_uniform (cadet_id,uniform_id) VALUES (?,?)');
    $cadetHasUniforms = array(
        1=>array(1,2,3), // <- cadetA
        2=>array(7,9), // <- cadetB
        3=>array(8,5,4), // <- cadetC
        // 4=>array() <- cadetD, no entry, no uniforms
        5=>array(10,13,15) // <- cadetE
        // <- cadetE, no entry, no uniforms
    );
    foreach( $cadetHasUniforms as $cadetId=>$uniformIds ) {
        foreach( $uniformIds as $uid ) {
            $stmt->execute(array($cadetId, $uid));
        }
    }

}

prints

uniforms of cadetB
cadetB, 7, labelQ
cadetB, 9, labelS
cadets without uniforms
cadetD
cadetF
share|improve this answer
Fantastic answer! I need to look into the PDO, this looks like a good excuse for me to do it! I will mark this as accepted (as it has worked around the problem) and is a fantastic answer! – zomboble Nov 8 '12 at 11:24
add comment (requires an account with 50 reputation)

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.