Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 4 of 4
  1. #1
    gwh
    gwh is offline
    New Coder
    Join Date
    Sep 2005
    Posts
    37
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Help revising class code

    Hi everyone,

    Before beginning I just wanted to say I've posted the full page code, as well as the custom class code at the end of this post.

    I've been trying to solve a problem with a php form that has an error on submit. The error I've been getting is as follows:

    Fatal error: Cannot use object of type MyResult as array in /Applications/MAMP/htdocs/newsite/admin/insertNewGarment.php on line 109

    Line 109 refers to this line:

    $values[$garment_id]['colour'] = $colours[$i];

    Even though I'm getting this error, the form seems to function partially in that it inserts the information into my database table.

    The part doesn't work and which I assume is related to the error is the following code:

    PHP Code:
    // build array of garment_id/category_id pairs, garment_id/colour_id pairs, and garment_id/size_id pairs one for each category, colour and size

    $values = array();
    $i 0;

    foreach (
    $_POST['category'] as $categories); {
        
    $values[$garment_id]['category'] = $categories;
        
    $values[$garment_id]['colour'] =  $colours[$i];
        
    $values[$garment_id]['size'] = $sizes[$i];
        
    $i++;
        }

    // insert garment_id/category_id, garment_id/color_id, and garment_id/size_id pairs into garment to category, garment to color, and garment to size lookup tables

             
    $k array_keys($values);
    foreach( 
    $k as $key ) {
        
    $cat_sql "INSERT INTO garment_to_category (garment_id, category_id) VALUES ($key, {$values[$key][category]})";
        
    $colour_sql "INSERT INTO garment_to_colour (garment_id, colour_id) VALUES ($key, {$values[$key][colour]})";
        
    $size_sql "INSERT INTO garment_to_size (garment_id, size_id) VALUES ($key, {$values[$key][size]})";


        
    $result $db->query($cat_sql);
        
    $result $db->query($colour_sql);
        
    $result $db->query($size_sql);

    I've been told that the problem relates to the custom class called "MyResult", which apparently needs some more functionality.

    I was told to "implement the ArrayAccess interface from SPL" and to change the code in the class as follows:

    class MyResult implements ArrayAccess

    Once that line is in place, you'll need to implement four methods:

    offsetSet($offset, $value)
    offsetGet($offset)
    offsetExists($offset)
    offsetUnset($offset)

    The names of these methods should be fairly self explanatory. To make MyResult read only, you can implement offsetSet as

    public function offsetSet($offset, $value) {}

    The other methods are fairly straighforward. Once they are implemented, you can use the MyResult object as an array.
    The problem is that I have very limited knowledge in how to revise class code - the instructions given weren't that clear. Can someone tell me if I need to replace the following block of code in my class file:

    PHP Code:
    class MyResult {

      protected 
    $theResult;
      public 
    $num_rows;
      
      function 
    __construct($r) {
          if (
    is_bool($r)) {
              
    $this->num_rows 0;
                }
            else {
              
    $this->theResult $r;
              
    // get total number of records found
              
    $this->num_rows mysqli_num_rows($r);
                }
          } 
    ...with the following code?

    PHP Code:
    class MyResult implements ArrayAccess

    offsetSet
    ($offset$value)
    offsetGet($offset)
    offsetExists($offset)
    offsetUnset($offset)

    public function 
    offsetSet($offset$value) {} 
    If so, is the above new code block syntax correct - I mean do I paste it exactly as above or am I missing some curly brackets etc.?

    I'm not sure if revising the class code as advised above will eliminate the error and provide the functionality needed in order to make the code that I mentioned at the beginning of this post work. I'd just really appreciate someone helping so I can move a few steps forward.


    PHP Code:
    <?php
    require_once('classes/database.php');
    // this code always runs, and gets lists of suppliers and garment categories
    $db=new Database('localhost','root','password','catalogue',0);
    $getSuppliers 'SELECT * FROM suppliers ORDER BY supplier';
    $suppliers $db->query($getSuppliers);
    $getGarment_types 'SELECT * FROM garment_types ORDER BY garment_type';
    $garment_types $db->query($getGarment_types);
    $getCategories 'SELECT * FROM categories ORDER BY category';
    $categories $db->query($getCategories);
    $getColours 'SELECT * FROM colours ORDER BY colour';
    $colours $db->query($getColours);
    $getSizes 'SELECT * FROM sizes ORDER BY size';
    $sizes $db->query($getSizes); 
    // this first block runs only if the form has been submitted
    if ($_POST) {
      
    // check for empty fields
      
    foreach($_POST as $key=>$value) {
        
    // category and colour are sub-arrays, so skip
        
    if (is_array($value)) continue;
          if (
    $key == 'extrainfo') continue;
        
    $value trim($value);
        if (empty(
    $value)) {
          if (
    $key == 'stylenum') {
            
    $error[] = 'You must enter a style number';
            }
          
    // if no supplier selected, value is 0, considered empty by PHP
          
    elseif ($key == 'supplier') {
            
    $error[] = 'You must select a supplier';
            }
          elseif (
    $key == 'sizes') {
            
    $error[] = 'You must select a size'
            }
          elseif (
    $key == 'garment_type') {
            
    $error[] = 'You must select a garment type';
            }
          else {
            
    $error[] = ucfirst($key).' is required';
            }
          }
        }
                
    // check that a garment category has been chosen
            
    if ($_POST['category'][0] == 'choose' && count($_POST['category']) <= 1) {
        
    $error[] = 'Select at least one category, or choose "Not listed"';
        }
                
    // check that a garment colour has been chosen
      
    if ($_POST['colour'][0] == 'choose' && count($_POST['colour']) <= 1) {
        
    $error[] = 'Select at least one colour, or choose "Not listed"';
        }
      
    // if all fields correctly filled, prepare to insert in database
      
    if (!isset($error)) {
        
    // final preparations for insertion
          // escape quotes and apostrophes if magic_quotes_gpc off
        
    if (!get_magic_quotes_gpc()) {
          foreach(
    $_POST as $key=>$value) {
            
    // skip category and colour sub-arrays
            
    if (is_array($value)) continue;
            
    $temp addslashes($value);
            
    $_POST[$key] = $temp;
            }
          }
        
    // create a Database instance, and set error reporting to plain text
        
    $db = new Database('localhost','root','password','catalogue',0);
        
    // first check that the same style number and supplier combination doesn't already exist
          
    $stylenum $_POST['stylenum'];
          
    $supplier $_POST['supplier'];
          
    $checkCode "SELECT stylenum FROM garments WHERE stylenum = '$stylenum' AND supplier_id = '$supplier'";
            
    $result $db->query($checkCode);
        if (
    $result->num_rows 0) {
          
    $error[] = 'A garment with that code and supplier already exists in the database';
          }
        else {
        
    // if style number and supplier combination unique, insert garment into garments table
          
    foreach($_POST as $key=>$val){
          if(
    $val == 'other'$_POST[$key] = "0";
          }
            
    $insert 'INSERT INTO garments (supplier_id, garment_type_id, title, stylenum, description, extra_info,image, swatch_image)
          VALUES ("'
    .$_POST['supplier'].'","'.$_POST['garment_type'].'","'.$_POST['title'].'","'.$_POST['stylenum'].'","'.$_POST['description'].'","'.$_POST['extrainfo'].'","'.$_POST['image'].'","'.$_POST['swatch'].'")';
          
    $result $db->query($insert);
          
    // get the primary key of the record just inserted
            
    $getGarment_id 'SELECT garment_id FROM garments
                         WHERE stylenum = "'
    .$_POST['stylenum'].'"';
          
    $result $db->query($getGarment_id);
          
    $row $result->fetch_assoc();
          
    $garment_id $row['garment_id'];
            
            
    // if "Select category(s)" and "Select colour(s) still selected, remove from the array
          
    if ($_POST['category'][0] == 'choose' || $_POST['colour'][0] == 'choose'){
          
    array_shift($_POST['category']);
          
    array_shift($_POST['colour']);
    }

    if (
    in_array('other'$_POST['category'])) {
          
    $i array_keys($_POST['category'],'other');
          
    $_POST['category'][$i] = 0;
    }
    if (
    in_array('other'$_POST['colour'])) {
          
    $i array_keys($_POST['colour'],'other');
          
    $_POST['colour'][$i] = 0;
    }

    // build array of garment_id/category_id pairs, garment_id/colour_id pairs, and garment_id/size_id pairs one for each category, colour and size

    $values = array();
    $i 0;

    foreach (
    $_POST['category'] as $categories); {
          
    $values[$garment_id]['category'] = $categories;
          
    $values[$garment_id]['colour'] =  $colours[$i];
          
    $values[$garment_id]['size'] = $sizes[$i];
          
    $i++;
          }

    // insert garment_id/category_id, garment_id/color_id, and garment_id/size_id pairs into garment to category, garment to color, and garment to size lookup tables

                 
    $k array_keys($values);
    foreach( 
    $k as $key ) {
          
    $cat_sql "INSERT INTO garment_to_category (garment_id, category_id) VALUES ($key, {$values[$key][category]})";
          
    $colour_sql "INSERT INTO garment_to_colour (garment_id, colour_id) VALUES ($key, {$values[$key][colour]})";
          
    $size_sql "INSERT INTO garment_to_size (garment_id, size_id) VALUES ($key, {$values[$key][size]})";


          
    $result $db->query($cat_sql);
          
    $result $db->query($colour_sql);
          
    $result $db->query($size_sql);
    }
          
    // if successful, redirect to confirmation page
          
    if ($result) {
              
    $db->close();
            
    header('Location: listGarments.php?action=inserted&title='.$_POST['title']);
            }
          }
          }
      }
    ?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml"><!-- InstanceBegin template="/Templates/AdminTemplate.dwt" codeOutsideHTMLIsLocked="false" -->
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    <!-- InstanceBeginEditable name="doctitle" -->
    <title>Insert new garment</title>
    <!-- InstanceEndEditable -->
    <link href="../main.css" rel="stylesheet" type="text/css" />
    <link href="admin.css" rel="stylesheet" type="text/css" />

    <script type="text/javascript" src="../p7pm/p7popmenu.js"></script>
    <style type="text/css" media="screen">
    <!--
    @import url("../p7pm/p7pmh2.css");
    -->
    </style>
    <!--[if lt IE 7]>
    <link href="../win_ie.css" rel="stylesheet" type="text/css" />
    <![endif]-->
    <style type="text/css"></style>
    <script language="JavaScript" type="text/JavaScript">
    <!--
    function Lvl_openWin(u,n,w,h,l,t,c,f) { //v2.2 4LevelWebs
      var x=((screen.width-w)/2);if(c==1){l=x;t=(screen.height-h)/2;}if(c==2){l=x}
          f+=',top='+t+',left='+l;LvlWin=window.open(u,n,f);LvlWin.focus();
    }
    //-->
    </script>
    <!-- InstanceBeginEditable name="head" --><!-- InstanceEndEditable -->
    </head>
    <body onload="P7_initPM(1,2,1,-20,10)">
    <div id="topstrip"></div>
    <div id="header"></div>
    <div id="navcorp">
      <ul id="p7PMnav">
        <li><a href="#" class="p7PMtrg" id="height">List garments</a>
            <ul>
              <li><a href="#">List suppliers</a></li>
              <li><a href="#">List categories</a></li>
              <li><a href="#">List garment types</a></li>
              <li><a href="#">List colours</a></li>
              <li><a href="#">List sizes</a></li>
            </ul>
        </li>
        <li><a href="#" class="p7PMtrg" id="height">Add new garment</a>
            <ul>
              <li><a href="#">Add new supplier</a></li>
              <li><a href="#">Add new category</a></li>
              <li><a href="#" id="unique">Add new garment type</a></li>
              <li><a href="#">Add new colour</a></li>
              <li><a href="#">Add new size</a></li>
            </ul>
        </li>
        <li><a href="#" class="p7PMtrg" id="height">Register new user</a>
            <ul>
              <li><a href="#">List registered users</a></li>
            </ul>
        </li>
        <li><a href="#" id="height">View Catalogue</a></li>
        <li><a href="#">Logout</a></li>
        <!--[if lte IE 6]><style>#p7PMnav a{height:1em;}#p7PMnav li{height:1em;}#p7PMnav ul li{float:left;clear:both;width:100%}</style><![endif]-->
        <!--[if IE 6]><style>#p7PMnav ul li{clear:none;}</style><![endif]-->
      </ul>
    </div>

    <!-- InstanceBeginEditable name="EditRegion3" -->
    <div id="background">
      <div id="wrapper">
        <div id="innerlayer">
          <h1>Insert new garment</h1>
            <?php
    if (isset($error)) {
      echo 
    '<div id="alert"><p>Please correct the following:</p><ul>';
      foreach (
    $error as $item) {
        echo 
    "<li>$item</li>";
          }
      echo 
    '</ul></div>';
      }
    ?>
          <form id="garmentDets" name="garmentDets" method="post" action="<?php $_SERVER['PHP_SELF']; ?>">
            <table id="garmentInsert" cellpadding="0">
                
              <tr>
                <th width="180" class="labelLeft">Supplier</th>
                <td colspan="2"><select name="supplier" id="supplier">
                    <option value="0" selected="selected">Select supplier</option>
                    <option value="other">Not listed</option>
                            <?php
          
    while ($row $suppliers->fetch_assoc()) {
            echo 
    '<option value="'.$row['supplier_id'].'">'
            echo 
    $row['supplier'].'</option>';
            }
          
    ?>
          </select>
                </td>
              </tr>
                  
              <tr>
                <th class="labelLeft">Garment type</th>
                <td colspan="2"><select name="garment_type" id="garment_type">
                    <option value="0" selected="selected">Select garment type</option>
                    <option value="other">Not listed</option>
                                                                        <?php
          
    while ($row $garment_types->fetch_assoc()) {
            echo 
    '<option value="'.$row['garment_type_id'].'">'
            echo 
    $row['garment_type'].'</option>';
            }
            
    ?>
                  </select>
                </td>
              </tr>
                 
              <tr>
                <th class="labelLeft">Garment category(s)</th>
                <td colspan="2"><select name="category[]" size="6" multiple="multiple" id="category">
                    <option value="choose" selected="selected">Select garment category(s)</option>
                    <option value="other">Not listed</option>
             <?php
           
    while ($row $categories->fetch_assoc()) {
             echo 
    '<option value="'.$row['category_id'].'">'
             echo 
    $row['category'].'</option>';
             }
           
    ?>
                  </select>
                </td>
              </tr>
              <tr>
                <th class="labelLeft">Title</th>
                <td colspan="2"><input name="title" type="text" class="widebox" id="title" /></td>
              </tr>
              <tr>
                <th class="labelLeft" scope="row">Style Number </th>
                <td colspan="2"><input name="stylenum" type="text" class="narrowbox" id="stylenum" /></td>
              </tr>
              <tr>
                <th class="labelLeft" scope="row">Description</th>
                <td colspan="2"><textarea name="description" id="description"></textarea></td>
              </tr>
              <tr>
                <th class="labelLeft" scope="row">Extra info </th>
                <td colspan="2"><input name="extrainfo" type="text" class="widebox" id="extrainfo" /></td>
              </tr>
              <tr>
                <th class="labelLeft" scope="row">Colours</th>
                <td colspan="2"><select name="colour[]" size="6" multiple="multiple" id="colour">
                    <option value="choose" selected="selected">Select colour(s)</option>
                    <option value="other">Not listed</option>
                                                                        <?php
          
    while ($row $colours->fetch_assoc()) {
            echo 
    '<option value="'.$row['colour_id'].'">'
            echo 
    $row['colour'].'</option>';
            }
          
    ?>
                  </select>

                </td>
              </tr>
              <tr>
                <th class="labelLeft" scope="row">Swatch image </th>
                <td colspan="2">Yes
                  <input name="swatch" type="radio" value="y" />
                  No
                  <input name="swatch" type="radio" value="n" /></td>
              </tr>
              <tr>
                <th class="labelLeft" scope="row">Sizes</th>
                <td colspan="2"><select name="sizes" id="sizes">
                    <option value="0" selected="selected">Select sizes</option>
                    <option value="other">Not listed</option>
                                                              <?php
          
    while ($row $sizes->fetch_assoc()) {
            echo 
    '<option value="'.$row['size_id'].'">'
            echo 
    $row['size'].'</option>';
            }
              
    // close database connection
          
    $db->close();
            
    ?>
                        </select>
                </td>
              </tr>
              <tr>
                <th class="labelLeft" scope="row">Image</th>
                <td width="190">Yes
                  <input name="image" type="radio" value="y" />
                  No
                  <input name="image" type="radio" value="n" /></td>
                <td id="garmentSubmit"><input type="submit" name="Submit" value="Insert new garment" /></td>
              </tr>
            </table>
          </form>
        </div>
      </div>
    </div>
    <!-- InstanceEndEditable --><img src="../Images/transparent.gif" width="1" height="1"/>
    <div id="footer">&copy; Copyright 2007. All rights reserved. </div>
    </body>
    <!-- InstanceEnd --></html>
    PHP Code:
    <?php
    class Database {

      protected 
    $host;
      protected 
    $user;
      protected 
    $pwd;
      protected 
    $dbName;
      protected 
    $flash;
      protected 
    $dbLink;
      protected 
    $result;
      protected 
    $resultObj;

      function 
    __construct($host$user$pwd$dbName$flash=1){
        
    $this->host $host;
        
    $this->user $user;
        
    $this->pwd $pwd;
        
    $this->dbName $dbName;
        
    $this->flash $flash;
          
    $this->connect();
        }

      
    // Connect to the mySQL Server and Select the database
      
    public function connect() {
        try {
          
    $this->dbLink = @mysqli_connect($this->host$this->user$this->pwd$this->dbName);
          if (!
    $this->dbLink) {
            throw new 
    Exception ("Couldn't connect $this->user to $this->dbName");
            }
          }
        catch (
    Exception $e) {
          echo 
    $this->flash 'error='.urlencode($e->getMessage()) : $e->getMessage();
          exit();
          }
        return 
    $this->dbLink;
        }

      
    // Execute an SQL query
      
    public function query($query) {
        try {
          
    $this->result mysqli_query($this->dbLink$query);
          if (!
    $this->result) {
            throw new 
    Exception ('MySQL Error: ' mysqli_error($this->dbLink));
            }
          }
        catch (
    Exception $e) {
          echo 
    $this->flash 'error='.urlencode($e->getMessage()) : $e->getMessage();
          exit();
          }
          
    // store result in new object to emulate mysqli OO interface
          
    $this->resultObj = new MyResult($this->result);
          return 
    $this->resultObj;
        }

      
    // Close MySQL Connection
      
    public function close(){
        
    mysqli_close($this->dbLink);
        }      
      }

    class 
    MyResult {

      protected 
    $theResult;
      public 
    $num_rows;
      
      function 
    __construct($r) {
          if (
    is_bool($r)) {
              
    $this->num_rows 0;
                }
            else {
              
    $this->theResult $r;
              
    // get total number of records found
              
    $this->num_rows mysqli_num_rows($r);
                }
          }
      
      
    // fetch associative array of result (works on one row at a time) 
      
    function fetch_assoc() {
        
    $newRow mysqli_fetch_assoc($this->theResult);
          return 
    $newRow;
          }
      }
    ?>

  • #2
    UE Antagonizer Fumigator's Avatar
    Join Date
    Dec 2005
    Location
    Utah, USA, Northwestern hemisphere, Earth, Solar System, Milky Way Galaxy, Alpha Quadrant
    Posts
    7,691
    Thanks
    42
    Thanked 637 Times in 625 Posts
    I took a look at your code and while I am not very quick with OO code, I don't think you need to add that offset stuff to the MyResult class. The mistake is in the misuse of the $colours variable-- it is defined as an object that contains (represents is perhaps a better word) a query resource, but doesn't contain the actual data from that resource. You have to call the fetch_assoc() function of that class to actually pull the data out of the query.

    So you should be able to leave the class untouched and simply modify the code around that line 109 to properly pull the data out of the query and then assign it to $values[$garment_id]['colour']. (line 285 does just that, FYI)

  • #3
    gwh
    gwh is offline
    New Coder
    Join Date
    Sep 2005
    Posts
    37
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Thanks for your reply,

    It would be great if the solution were that simple. I'm not actually sure how to combined lines 285 and 109 below - can you be more specific as to how to do this?

    Line 285
    while ($row = $colours->fetch_assoc()) {

    Line 109

    $values[$garment_id]['colour'] = $colours[$i];

  • #4
    UE Antagonizer Fumigator's Avatar
    Join Date
    Dec 2005
    Location
    Utah, USA, Northwestern hemisphere, Earth, Solar System, Milky Way Galaxy, Alpha Quadrant
    Posts
    7,691
    Thanks
    42
    Thanked 637 Times in 625 Posts
    Don't combine the two lines, just do what line 285 is doing. Right now you're using $colours as if it were the array built from the fetch_assoc() function in your MyResult class, but it's not the case... you simply need to call that function to get your data.

    I take it you didn't write this code. The solution really is that simple... it may take some research on your part to figure out the PHP language, but once you do then you'll have gained tons of valuable PHP skillz. Use www.php.net as a reference.


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •