views:

74

answers:

8

Say there is a special php function named foo($number) that returns double the value of its input. Further, say there is a table that contains the column "number." Is there a way so that I can run a query and get the following:

Number | Double
================
1 | 2
5 | 10
+1  A: 

You don't need to use PHP. You can just execute a regular SQL statement as follows.

SELECT number, number * 2 FROM tablename;
Rachel McMahan
A: 
//Your query would prob be like so.
$query = mysql_query("SELECT (number * 2) as double,number FROM table");

echo '<table>';
while($row = mysql_fetch_assoc($query))
{
    echo sprintf('<tr><td>%d</td><td>%d</td></tr>',$row['number'],$row['double']);
}
echo '</table>';
RobertPitt
what i want to do is combine php along with sql without having to iterate over,something like this"SELECT Number, foo($number) AS 'Double' FROM Table1"remember foo() is php function
Aman
can explain the perpose of what you would want to do that for, you cant use php functions via mysql unless your iterate of the fetched!data.
RobertPitt
+2  A: 

No, since the query results come straight from MySQL. You can apply the function to the result set after you execute your query, either by using a loop or by applying your function to the results using array_map() function.

Anax
A: 

I think I understand your question.

It sounds as though you want to pull a number from a database and double it through a php function.

I would first learn to write the php function... Check this out for a tutorial.

Once you have that down, pull your number from the database. Here is a tutorial on how to do that.

This is all about learning. Me posting code for you to just copy doesn't help you learn and is basically a waste of my time. Best of luck.

Capt Otis
lol, thanx I was thinking if it was possible to combine php function and mysql result without iterating over the result
Aman
A: 

It depends on what the function is doing. Basic stuff like arithmetic can be done with SQL directly. Otherwise, you can loop over the result array and run the function in the particular field, e.g.:

$rows = array();
foreach(($row = mysql_fetch_assoc($result))) {
    $row['double'] = func($row['number']);
    rows[] = $row;
}
Felix Kling
A: 

No, it's impossible to use php function() and sql together
However, you can get results from SQL database and apply whatever PHP function on it

Col. Shrapnel
+1  A: 

Depending on what you're actually trying to achieve it might be possible to decouple the data source and the consumer a bit, enough to put another component between them.

Let's start with

<?php
$result = getData($pdo); // a)
doSomething($result); // b)

function getData($mysql) {
  return mysql_query('SELECT x FROM soTest', $mysql);
}

function doSomething($result) {
  while ( false!==($row=mysql_fetch_assoc($result)) ) {
    echo ' ', join(', ', $row), "\n";
  }
  echo "----\n";
}

There's very little you can do to alter a mysql result resource. And doSomething() does nothing more than iterating over the result set. It does nothing that is special to a mysql result set, yet it allows nothing else but this exact resource type by using mysql_fetch_xyz().
Let's try this again using PDO (PDO_MYSQL).

$result = getData($pdo);
doSomething($result);

function getData($pdo) {
  return $pdo->query('SELECT x FROM soTest');
}

function doSomething(PDOStatement $result) {
  while ( $row=$result->fetch(PDO::FETCH_ASSOC) ) {
    echo ' ', join(', ', $row), "\n";
  }
  echo "----\n";
}

That didn't change much. Some names but essentially this is the same. But PDOStatement implements the Traversable interface, so you can use it directly with foreach.

$result = getData($pdo);
doSomething($result);

function getData($pdo) {
  return $pdo->query('SELECT x FROM soTest', PDO::FETCH_ASSOC);
}

function doSomething($traversable) {
  foreach( $traversable as $row ) {
    echo ' ', join(', ', $row), "\n";
  }
  echo "----\n";
}

That's a game changer... We can pass any traversable/iterator to doSomething() and it still does more or less the same thing as before.
Now we can put something "between" getData() and doSomething(). This something takes an inner iterator (like getData() provides in the form of an PDOStatement) and behaves itself like an iterator (so DoSomething() can use it) returning all elements of its inner iterator but modifying some elements.
I chose to extend FilterIterator for this example for no particular reason. You need php 5.3+ to run this demo since it uses an anonymous function:

<?php
$pdo = initDemo();

echo "#1: passing \$result\n";
$result = getData($pdo); // a)
doSomething($result); // b)

echo "#2: passing ModifyIterator\n";
$result = getData($pdo); // exact same as a)
$result = new ModifyIterator($result, null, function($e) {
  $e['y'] = '/' . ($e['x'] * 2) .'/';
  return $e;
});
doSomething($result);  // exact same as b)

function getData($pdo) {
  return $pdo->query('SELECT x FROM soTest', PDO::FETCH_ASSOC);
}  

function doSomething($traversable) {
  foreach($traversable as $row) {
    echo ' ', join(', ', $row), "\n";
  }
  echo "----\n";
}

class ModifyIterator extends FilterIterator {
  protected $fnAccept, $fnModify;
  public function __construct($it, $fnAccept, $fnModify) {
    // todo: test parameters!
    $this->fnAccept = $fnAccept;
    $this->fnModify = $fnModify;
    if ( !($it instanceof Iterator) ) {
      $it = new IteratorIterator($it);
    }
    parent::__construct($it);
  }

  public function accept() {
    return $this->fnAccept ? $this->fnAccept(parent::current()) : true;
  }

  public function current() {
    if ( $this->fnModify ) {
      $fn = $this->fnModify;
      return $fn(parent::current());
    }
    return parent::current();
  }
}

function initDemo() {
  $pdo = new PDO('mysql:host=localhost;dbname=test', 'localonly', 'localonly');
  $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  $pdo->exec('CREATE TEMPORARY TABLE soTest (x int auto_increment, primary key(x))');
  $pdo->exec('INSERT INTO soTest VALUES (),(),(),(),()');
  return $pdo;
}

prints

#1: passing $result
 1
 2
 3
 4
 5
----
#2: passing ModifyIterator
 1, /2/
 2, /4/
 3, /6/
 4, /8/
 5, /10/
----

The important part is that ModifyIterator forces very little particular behaviour on the inner iterator (e.g. you can still use an unbuffered query without the need to transfer all the data into the php process' memory at once) and that both getData() and doSomething() are left unchanged.

VolkerK
thanx a lot this looks very interesting, i will try this demo
Aman
+1  A: 

One way would be to fetch the results into objects:

class NumberDoubler
{
    public $number;

    public function __construct()
    {
        $this->number *= 2;
    }
}

$pdo = new PDO('mysql:host=localhost;dbname=db_name', 'uname', 'pword');
$stmnt = $pdo->query('SELECT number FROM db_table');
$result = $stmnt->fetchAll(PDO::FETCH_CLASS, 'NumberDoubler');

print_r($result);

The result will be an array of objects with '$number' doubled. Of course, iteration will still be done "behind the scenes", and the manual warns, "Using this method to fetch large result sets will result in a heavy demand on system and possibly network resources."

See also PDOStatement::setFetchMode().

GZipp
hummm.... this looks promising thanx
Aman