Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot use assign-op operators with overloaded objects nor string offsets

I have this portion of code and it gives me the error in the title.

I have a count $k from 1 to 5 for each table.

$myarray consists of at least 3 to 4 names.

The error occurs in the line with $qu .= ...

What i tried so far: changing the variablename $i to $v{$i} in the $qu .= line.

So is there any possibility to iterate the query? So that it has as many ANDs in the WHERE clause as the count of the array is?

while ($k<=5) {
  $queryname = "SELECT Name FROM description";
  $qname = mysql_query($queryname,$link);

  while ($reihe = mysql_fetch_object($qname)) {
    {
      $unse = unserialize($reihe->Name);
      {
        foreach ($unse as $j=>$h)
          foreach ($h as $m) {
            $myarray = preg_split('/ |\s| /',$m);
            {
              echo "<br>";
              $array_empty = $myarray;
              $empty_elements = array("");
              $myarray = array_diff($array_empty,$empty_elements);
              var_dump($myarray);
              for ($i=1; $i<=count($myarray); $i++) {
                $v{$i} = $myarray[$i];
                echo $v{$i};
                $esc{$i} = strtolower(mysql_escape_string($v{$i}));
                echo "<br>" . $esc{$i} . "<br>";
                $qu = "SELECT * FROM `table ID=$k` WHERE";
                $qu{$i} .= "AND `table ID=$k`.`name` LIKE '%$esc{$i}%'";
              }
            }
          }
        {
          $test_a = mysql_query($qu,$link) or die (mysql_error());
          echo "<br>";
          var_dump($test_a);
          for ($x=0; $x<mysql_num_rows($test_a); $x++) {
            $row = mysql_result($test_a,$x,'data1');
            $namee = mysql_result($test_a,$x,'data2');
            echo 'data1' . $row . '<br>';
            echo 'data2' . $namee . '<br>';
          }
        }
      }
    }
  }
  $k++;
}
like image 359
little_fck Avatar asked May 24 '12 17:05

little_fck


1 Answers

You appear to have misunderstood some basic PHP syntax.

As mentioned in the manual:

Characters within strings may be accessed and modified by specifying the zero-based offset of the desired character after the string using square array brackets, as in $str[42]. Think of a string as an array of characters for this purpose. The functions substr() and substr_replace() can be used when you want to extract or replace more than 1 character.

Note: Strings may also be accessed using braces, as in $str{42}, for the same purpose.

Therefore your use of curly braces throughout your code (except for those defining the scope of the for control structure) are wholly erroneous and do not accomplish what you intend.

Secondly, from your code it appears that you are storing relational data in serialised PHP objects; this defeats many of the benefits of using an RDBMS like MySQL. Unless you have compelling reasons for doing otherwise, you should probably store your PHP objects in a normalised form. For example, rather than each description record having a Name field that contains a serialised PHP object whose properties are arrays that hold imploded strings of names, just store each such name in a new descriptionNames table that references the related record in the description table:

CREATE TABLE descriptionNames (
  descriptionID INT NOT NULL,
  name VARCHAR(50),
  PRIMARY KEY (descriptionId, name),
  FOREIGN KEY (descriptionId) REFERENCES description (descriptionId)
);

It also appears that you have five (schematically) identical tables named Table ID=1, Table ID=2, etc.? If so, you should probably combine your five tables into one, with a column (if so desired) to indicate from which table the record originated; I would also suggest changing your table names so that they avoid using special characters like whitespace and = as they will likely only cause trouble and confusion further down the road if you forget to properly quote them. For example:

ALTER TABLE `Table ID=1`
  RENAME TO CombiTable,
  ADD COLUMN FromTableID TINYINT NOT NULL;

UPDATE CombiTable SET FromTableID = 1;

INSERT INTO CombiTable
  SELECT *, 2 FROM `Table ID=2` UNION ALL
  SELECT *, 3 FROM `Table ID=3` UNION ALL
  SELECT *, 4 FROM `Table ID=4` UNION ALL
  SELECT *, 5 FROM `Table ID=5`;

SELECT * FROM CombiTable;  -- check everything is okay

DROP TABLE `Table ID=2`, `Table ID=3`, `Table ID=4`, `Table ID=5`;

In any event, you shouldn't use the ancient mysql_* functions. They are no longer maintained and the community has begun the deprecation process. Instead you should learn about prepared statements and use either the PDO abstraction layer or else the improved MySQLi extension.

If you need to maintain your existing data structure, with PDO you could do something like:

$dbh = new PDO("mysql:dbname=$dbname;charset=utf8", $user, $password);

$qry = $dbh->query("SELECT Name FROM description");
$myarray = array();
while ($reihe = $dbh->fetchColumn())
  foreach (unserialize($reihe) as $h)
    foreach ($h as $m)
      array_merge($myarray, preg_split("/\s+/", $m, -1, PREG_SPLIT_NO_EMPTY));

for ($k = 1; $k <= 5; $k++) {
  $qry = $dbh->prepare("SELECT * FROM `table ID=$k` WHERE " . implode(" OR ",
    array_pad(array(), count($myarray), "name LIKE CONCAT('%', ?, '%')")
  ));

  $qry->execute($myarray);
  while($row = $qry->fetch()) {
    echo "data1:$row[data1]<br/>";
    echo "data2:$row[data2]<br/>";
  }
}

However, using my proposed new data structure, you would only need do:

$dbh = new PDO("mysql:dbname=$dbname;charset=utf8", $user, $password);

$qry = $dbh->query("
  SELECT   *
  FROM     CombiTable JOIN descriptionNames USING (name)
  WHERE    FromTableID BETWEEN 1 AND 5   -- in case you have others?
  ORDER BY FromTableID
");

while ($row = $qry->fetch()) {
  echo "data1:$row[data1]<br/>";
  echo "data2:$row[data2]<br/>";
}
like image 108
eggyal Avatar answered Nov 18 '22 12:11

eggyal