Commit 035d8de3 authored by doctrine's avatar doctrine

--no commit message

--no commit message
parent 2d4db7b0
...@@ -37,6 +37,14 @@ class Doctrine_Cache implements iDoctrine_Cache { ...@@ -37,6 +37,14 @@ class Doctrine_Cache implements iDoctrine_Cache {
public function fetch($id) { public function fetch($id) {
throw new InvalidKeyException(); throw new InvalidKeyException();
} }
/**
* implemented by child classes
* @param array $keys
* @return boolean
*/
public function fetchMultiple($keys) {
return false;
}
/** /**
* implemented by child classes * implemented by child classes
* @param integer $id * @param integer $id
...@@ -48,7 +56,7 @@ class Doctrine_Cache implements iDoctrine_Cache { ...@@ -48,7 +56,7 @@ class Doctrine_Cache implements iDoctrine_Cache {
/** /**
* implemented by child classes * implemented by child classes
*/ */
public function deleteMultiple() { public function deleteMultiple($keys) {
return 0; return 0;
} }
/** /**
......
...@@ -16,7 +16,7 @@ class Doctrine_Cache_Sqlite { ...@@ -16,7 +16,7 @@ class Doctrine_Cache_Sqlite {
* INSERT constant * INSERT constant
* used as a base for SQL INSERT queries * used as a base for SQL INSERT queries
*/ */
const INSERT = "INSERT INTO %s (id, object) VALUES (?, ?)"; const INSERT = "REPLACE INTO %s (id, object) VALUES (?, ?)";
/** /**
* DELETE constant * DELETE constant
* used as a base for SQL DELETE queries * used as a base for SQL DELETE queries
...@@ -44,13 +44,10 @@ class Doctrine_Cache_Sqlite { ...@@ -44,13 +44,10 @@ class Doctrine_Cache_Sqlite {
mkdir($dir, 0777); mkdir($dir, 0777);
$this->path = $dir.DIRECTORY_SEPARATOR; $this->path = $dir.DIRECTORY_SEPARATOR;
$this->dbh = $this->table->getSession()->getCacheHandler();
$this->dbh = new PDO("sqlite:".$this->path."data.cache");
$this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->dbh->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER);
try { try {
$this->dbh->query("CREATE TABLE ".$this->table->getTableName()." (id INTEGER, object TEXT)"); $this->dbh->query("CREATE TABLE ".$this->table->getTableName()." (id INTEGER UNIQUE, object TEXT)");
} catch(PDOException $e) { } catch(PDOException $e) {
} }
...@@ -76,11 +73,12 @@ class Doctrine_Cache_Sqlite { ...@@ -76,11 +73,12 @@ class Doctrine_Cache_Sqlite {
$stmt = $this->dbh->query(sprintf(self::INSERT,$this->table->getTableName())); $stmt = $this->dbh->query(sprintf(self::INSERT,$this->table->getTableName()));
$stmt->execute(array($id, serialize($clone))); $stmt->execute(array($id, serialize($clone)));
return true; return true;
} }
/** /**
* fetches a Doctrine_Record from the cache * fetches a Doctrine_Record from the cache
* @param integer $id * @param mixed $id
* @return mixed false on failure, Doctrine_Record on success * @return mixed false on failure, Doctrine_Record on success
*/ */
public function fetch($id) { public function fetch($id) {
...@@ -109,8 +107,10 @@ class Doctrine_Cache_Sqlite { ...@@ -109,8 +107,10 @@ class Doctrine_Cache_Sqlite {
*/ */
public function fetchMultiple(array $keys) { public function fetchMultiple(array $keys) {
$count = (count($keys)-1); $count = (count($keys)-1);
$keys = array_values($keys);
$sql = sprintf(self::SELECT,$this->table->getTableName(),"IN (".str_repeat("?, ",$count)."?)"); $sql = sprintf(self::SELECT,$this->table->getTableName(),"IN (".str_repeat("?, ",$count)."?)");
$stmt = $this->dbh->query($sql); $stmt = $this->dbh->query($sql);
$stmt->execute($keys); $stmt->execute($keys);
while($data = $stmt->fetch(PDO::FETCH_NUM)) { while($data = $stmt->fetch(PDO::FETCH_NUM)) {
...@@ -133,6 +133,7 @@ class Doctrine_Cache_Sqlite { ...@@ -133,6 +133,7 @@ class Doctrine_Cache_Sqlite {
return $stmt->rowCount(); return $stmt->rowCount();
} }
/** /**
* @param mixed $id
* @return void * @return void
*/ */
public function delete($id) { public function delete($id) {
...@@ -163,6 +164,7 @@ class Doctrine_Cache_Sqlite { ...@@ -163,6 +164,7 @@ class Doctrine_Cache_Sqlite {
if(empty($keys)) if(empty($keys))
return 0; return 0;
$keys = array_values($keys);
$count = (count($keys)-1); $count = (count($keys)-1);
$sql = sprintf(self::DELETE,$this->table->getTableName(),"IN (".str_repeat("?, ",$count)."?)"); $sql = sprintf(self::DELETE,$this->table->getTableName(),"IN (".str_repeat("?, ",$count)."?)");
$stmt = $this->dbh->query($sql); $stmt = $this->dbh->query($sql);
...@@ -245,7 +247,12 @@ class Doctrine_Cache_Sqlite { ...@@ -245,7 +247,12 @@ class Doctrine_Cache_Sqlite {
} }
return false; return false;
} }
/**
* @param mixed $id
*/
public function addDelete($id) {
$this->delete[] = $id;
}
/** /**
* destructor * destructor
* the purpose of this destructor is to save all the fetched * the purpose of this destructor is to save all the fetched
......
...@@ -83,18 +83,8 @@ class Doctrine_Collection_Batch extends Doctrine_Collection { ...@@ -83,18 +83,8 @@ class Doctrine_Collection_Batch extends Doctrine_Collection {
elseif(is_array($this->data[$i])) elseif(is_array($this->data[$i]))
$id = $this->data[$i]["id"]; $id = $this->data[$i]["id"];
$load = false;
// check the cache
// no need of fetching the same data twice
try {
$record = $this->table->getCache()->fetch($id);
} catch(InvalidKeyException $ex) {
$load = true;
}
if($load) $a[$i] = $id;
$a[] = $id;
endfor; endfor;
$c = count($a); $c = count($a);
...@@ -104,20 +94,21 @@ class Doctrine_Collection_Batch extends Doctrine_Collection { ...@@ -104,20 +94,21 @@ class Doctrine_Collection_Batch extends Doctrine_Collection {
$query .= substr(str_repeat("?, ",count($a)),0,-2); $query .= substr(str_repeat("?, ",count($a)),0,-2);
$query .= ($c > 1)?")":""; $query .= ($c > 1)?")":"";
$stmt = $this->table->getSession()->execute($query,$a); $stmt = $this->table->getSession()->execute($query,array_values($a));
while($row = $stmt->fetch(PDO::FETCH_ASSOC)): foreach($a as $k => $id) {
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if($row === false)
break;
$this->table->setData($row); $this->table->setData($row);
if(is_object($this->data[$e])) { if(is_object($this->data[$k])) {
$this->data[$e]->factoryRefresh($this->table); $this->data[$k]->factoryRefresh($this->table);
} else { } else {
$this->data[$e] = $this->table->getRecord(); $this->data[$k] = $this->table->getRecord();
} }
$e++; }
endwhile;
$this->loaded[$x] = true; $this->loaded[$x] = true;
return true; return true;
...@@ -134,20 +125,9 @@ class Doctrine_Collection_Batch extends Doctrine_Collection { ...@@ -134,20 +125,9 @@ class Doctrine_Collection_Batch extends Doctrine_Collection {
if(isset($this->data[$key])) { if(isset($this->data[$key])) {
switch(gettype($this->data[$key])): switch(gettype($this->data[$key])):
case "array": case "array":
try {
// try to fetch the Doctrine_Record from cache
if( ! isset($this->data[$key]["id"]))
throw new InvalidKeyException();
$this->data[$key] = $this->table->getCache()->fetch($this->data[$key]["id"]);
} catch(InvalidKeyException $e) {
// Doctrine_Record didn't exist in cache // Doctrine_Record didn't exist in cache
$this->table->setData($this->data[$key]); $this->table->setData($this->data[$key]);
$this->data[$key] = $this->table->getProxy(); $this->data[$key] = $this->table->getProxy();
}
$this->data[$key]->addCollection($this); $this->data[$key]->addCollection($this);
break; break;
......
...@@ -24,26 +24,40 @@ class Doctrine_DB extends PDO implements Countable, IteratorAggregate { ...@@ -24,26 +24,40 @@ class Doctrine_DB extends PDO implements Countable, IteratorAggregate {
$this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->setAttribute(PDO::ATTR_STATEMENT_CLASS, array("Doctrine_DBStatement",array($this))); $this->setAttribute(PDO::ATTR_STATEMENT_CLASS, array("Doctrine_DBStatement",array($this)));
} }
public static function getConn($dsn,$username = null, $password = null) {
static $instance;
if( ! isset($instance)) {
$instance = new Doctrine_DB($dsn,$username,$password);
}
return $instance;
}
/** /**
* @param string $dsn PEAR::DB like DSN * @param string $dsn PEAR::DB like DSN
* format: schema://user:password@address/dbname * format: schema://user:password@address/dbname
*/ */
public static function getConnection($dsn = null) { public static function getConnection($dsn = null) {
static $instance; static $instance = array();
if( ! isset($instance)) { $md5 = md5($dsn);
if( ! isset($instance[$md5])) {
if( ! isset($dsn)) { if( ! isset($dsn)) {
$a = parse_url(self::DSN); $a = parse_url(self::DSN);
} else { } else {
$a = parse_url($dsn); $a = parse_url($dsn);
} }
$e = array(); $e = array();
$e[0] = $a["scheme"].":host=".$a["host"].";dbname=".substr($a["path"],1); $e[0] = $a["scheme"].":host=".$a["host"].";dbname=".substr($a["path"],1);
$e[1] = $a["user"]; $e[1] = $a["user"];
$e[2] = $a["pass"]; $e[2] = $a["pass"];
$instance = new Doctrine_DB($e[0],$e[1],$e[2]); $instance[$md5] = new Doctrine_DB($e[0],$e[1],$e[2]);
} }
return $instance; return $instance[$md5];
} }
/** /**
* @param string $query query to be executed * @param string $query query to be executed
......
...@@ -173,8 +173,6 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite ...@@ -173,8 +173,6 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
unset($this->data['id']); unset($this->data['id']);
$this->table->setData(array()); $this->table->setData(array());
$this->table->getCache()->store($this);
} }
} }
/** /**
...@@ -331,7 +329,6 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite ...@@ -331,7 +329,6 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
$this->loaded = true; $this->loaded = true;
$this->state = Doctrine_Record::STATE_CLEAN; $this->state = Doctrine_Record::STATE_CLEAN;
$this->getTable()->getCache()->store($this);
return true; return true;
} }
/** /**
...@@ -353,8 +350,6 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite ...@@ -353,8 +350,6 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
$this->state = Doctrine_Record::STATE_CLEAN; $this->state = Doctrine_Record::STATE_CLEAN;
$this->modified = array(); $this->modified = array();
$this->loaded = true; $this->loaded = true;
$this->getTable()->getCache()->store($this);
} }
/** /**
* return the factory that created this data access object * return the factory that created this data access object
......
...@@ -60,6 +60,10 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab ...@@ -60,6 +60,10 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab
private $transaction_level = 0; private $transaction_level = 0;
private $validator; private $validator;
/**
* @var PDO $cacheHandler
*/
private $cacheHandler;
...@@ -77,8 +81,23 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab ...@@ -77,8 +81,23 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab
$this->dbh->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER); $this->dbh->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER);
$this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
switch($this->getAttribute(Doctrine::ATTR_CACHE)):
case Doctrine::CACHE_SQLITE:
$dir = $this->getAttribute(Doctrine::ATTR_CACHE_DIR).DIRECTORY_SEPARATOR;
$dsn = "sqlite:".$dir."data.cache";
$this->cacheHandler = Doctrine_DB::getConn($dsn);
$this->cacheHandler->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->cacheHandler->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER);
break;
endswitch;
$this->getAttribute(Doctrine::ATTR_LISTENER)->onOpen($this); $this->getAttribute(Doctrine::ATTR_LISTENER)->onOpen($this);
} }
public function getCacheHandler() {
return $this->cacheHandler;
}
/** /**
* @return integer the session state * @return integer the session state
*/ */
...@@ -435,8 +454,6 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab ...@@ -435,8 +454,6 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab
$record->getTable()->getAttribute(Doctrine::ATTR_LISTENER)->onInsert($record); $record->getTable()->getAttribute(Doctrine::ATTR_LISTENER)->onInsert($record);
$record->getTable()->getAttribute(Doctrine::ATTR_LISTENER)->onSave($record); $record->getTable()->getAttribute(Doctrine::ATTR_LISTENER)->onSave($record);
$record->getTable()->getCache()->store($record);
} }
} }
$this->insert = array(array()); $this->insert = array(array());
...@@ -448,6 +465,8 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab ...@@ -448,6 +465,8 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab
*/ */
public function bulkUpdate() { public function bulkUpdate() {
foreach($this->update as $name => $updates) { foreach($this->update as $name => $updates) {
$ids = array();
foreach($updates as $k => $record) { foreach($updates as $k => $record) {
$record->getTable()->getAttribute(Doctrine::ATTR_LISTENER)->onPreSave($record); $record->getTable()->getAttribute(Doctrine::ATTR_LISTENER)->onPreSave($record);
// listen the onPreUpdate event // listen the onPreUpdate event
...@@ -458,7 +477,11 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab ...@@ -458,7 +477,11 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab
$record->getTable()->getAttribute(Doctrine::ATTR_LISTENER)->onUpdate($record); $record->getTable()->getAttribute(Doctrine::ATTR_LISTENER)->onUpdate($record);
$record->getTable()->getAttribute(Doctrine::ATTR_LISTENER)->onSave($record); $record->getTable()->getAttribute(Doctrine::ATTR_LISTENER)->onSave($record);
$ids[] = $record->getID();
} }
if(isset($record))
$record->getTable()->getCache()->deleteMultiple($ids);
} }
$this->update = array(array()); $this->update = array(array());
} }
...@@ -611,7 +634,6 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab ...@@ -611,7 +634,6 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab
$record->setID($record->getID()); $record->setID($record->getID());
$record->getTable()->getCache()->delete($record->getID());
return true; return true;
} }
/** /**
......
...@@ -442,14 +442,6 @@ class Doctrine_Table extends Doctrine_Configurable { ...@@ -442,14 +442,6 @@ class Doctrine_Table extends Doctrine_Configurable {
*/ */
final public function find($id = null) { final public function find($id = null) {
if($id !== null) { if($id !== null) {
try {
// try to get from cache
$record = $this->cache->fetch($id);
return $record;
} catch(InvalidKeyException $e) {
// do nothing
}
$query = $this->query." WHERE ".implode(" = ? && ",$this->primaryKeys)." = ?"; $query = $this->query." WHERE ".implode(" = ? && ",$this->primaryKeys)." = ?";
$query = $this->applyInheritance($query); $query = $this->applyInheritance($query);
...@@ -510,14 +502,6 @@ class Doctrine_Table extends Doctrine_Configurable { ...@@ -510,14 +502,6 @@ class Doctrine_Table extends Doctrine_Configurable {
*/ */
final public function getProxy($id = null) { final public function getProxy($id = null) {
if($id !== null) { if($id !== null) {
$id = (int) $id;
try {
// try to get from cache
$record = $this->cache->fetch($id);
return $record;
} catch(InvalidKeyException $e) {
// do nothing
}
$query = "SELECT ".implode(", ",$this->primaryKeys)." FROM ".$this->getTableName()." WHERE ".implode(" = ? && ",$this->primaryKeys)." = ?"; $query = "SELECT ".implode(", ",$this->primaryKeys)." FROM ".$this->getTableName()." WHERE ".implode(" = ? && ",$this->primaryKeys)." = ?";
$query = $this->applyInheritance($query); $query = $this->applyInheritance($query);
...@@ -558,11 +542,7 @@ class Doctrine_Table extends Doctrine_Configurable { ...@@ -558,11 +542,7 @@ class Doctrine_Table extends Doctrine_Configurable {
foreach($data as $row) { foreach($data as $row) {
$this->data = $row; $this->data = $row;
try {
$record = $this->getCache()->fetch($this->data["id"]);
} catch(InvalidKeyException $e) {
$record = $this->getRecord(); $record = $this->getRecord();
}
$coll->add($record); $coll->add($record);
} }
return $coll; return $coll;
......
...@@ -12,7 +12,7 @@ class Doctrine_Cache_SqliteTestCase extends Doctrine_UnitTestCase { ...@@ -12,7 +12,7 @@ class Doctrine_Cache_SqliteTestCase extends Doctrine_UnitTestCase {
$this->cache = new Doctrine_Cache_Sqlite($this->objTable); $this->cache = new Doctrine_Cache_Sqlite($this->objTable);
$this->cache->deleteAll(); $this->cache->deleteAll();
} }
/**
public function testStore() { public function testStore() {
// does not store proxy objects // does not store proxy objects
$this->assertFalse($this->cache->store($this->objTable->getProxy(4))); $this->assertFalse($this->cache->store($this->objTable->getProxy(4)));
...@@ -104,8 +104,6 @@ class Doctrine_Cache_SqliteTestCase extends Doctrine_UnitTestCase { ...@@ -104,8 +104,6 @@ class Doctrine_Cache_SqliteTestCase extends Doctrine_UnitTestCase {
$this->manager->setAttribute(Doctrine::ATTR_CACHE_SIZE, 3); $this->manager->setAttribute(Doctrine::ATTR_CACHE_SIZE, 3);
$this->assertEqual($this->cache->clean(), 3); $this->assertEqual($this->cache->clean(), 3);
} }
*/
} }
?> ?>
...@@ -161,26 +161,6 @@ class Doctrine_RecordTestCase extends Doctrine_UnitTestCase { ...@@ -161,26 +161,6 @@ class Doctrine_RecordTestCase extends Doctrine_UnitTestCase {
$this->assertTrue($p->getObject() instanceof Doctrine_Session); $this->assertTrue($p->getObject() instanceof Doctrine_Session);
$this->assertTrue($p->getCode() == Doctrine_Debugger::EVENT_COMMIT); $this->assertTrue($p->getCode() == Doctrine_Debugger::EVENT_COMMIT);
if($this->manager->getAttribute(Doctrine::ATTR_CACHE) !== Doctrine::CACHE_NONE) {
$p = array_pop($debug);
$this->assertTrue($p->getObject() instanceof Doctrine_Record);
$this->assertTrue($p->getCode() == Doctrine_Debugger::EVENT_SLEEP);
}
$p = array_pop($debug);
$this->assertTrue($p->getObject() instanceof Doctrine_Record);
$this->assertTrue($p->getCode() == Doctrine_Debugger::EVENT_SAVE);
$p = array_pop($debug);
$this->assertTrue($p->getObject() instanceof Doctrine_Record);
$this->assertTrue($p->getCode() == Doctrine_Debugger::EVENT_INSERT);
$p = array_pop($debug);
$this->assertTrue($p->getObject() instanceof Doctrine_Record);
$this->assertTrue($p->getCode() == Doctrine_Debugger::EVENT_PREINSERT);
$this->new->delete(); $this->new->delete();
$this->assertTrue($this->new->getState() == Doctrine_Record::STATE_TCLEAN); $this->assertTrue($this->new->getState() == Doctrine_Record::STATE_TCLEAN);
} }
......
...@@ -61,6 +61,7 @@ class Doctrine_UnitTestCase extends UnitTestCase { ...@@ -61,6 +61,7 @@ class Doctrine_UnitTestCase extends UnitTestCase {
foreach($tables as $name) { foreach($tables as $name) {
$table = $this->session->getTable($name); $table = $this->session->getTable($name);
$table->getCache()->deleteAll();
} }
...@@ -128,6 +129,9 @@ class Doctrine_UnitTestCase extends UnitTestCase { ...@@ -128,6 +129,9 @@ class Doctrine_UnitTestCase extends UnitTestCase {
$this->users = $users; $this->users = $users;
$this->session->flush(); $this->session->flush();
} }
public function getSession() {
return $this->session;
}
public function clearCache() { public function clearCache() {
foreach($this->tables as $name) { foreach($this->tables as $name) {
$table = $this->session->getTable($name); $table = $this->session->getTable($name);
......
...@@ -36,13 +36,14 @@ $test->addTestCase(new Doctrine_AccessTestCase()); ...@@ -36,13 +36,14 @@ $test->addTestCase(new Doctrine_AccessTestCase());
$test->addTestCase(new Doctrine_ConfigurableTestCase()); $test->addTestCase(new Doctrine_ConfigurableTestCase());
$test->addTestCase(new Doctrine_EventListenerTestCase()); $test->addTestCase(new Doctrine_EventListenerTestCase());
$test->addTestCase(new Doctrine_DQL_ParserTestCase()); $test->addTestCase(new Doctrine_DQL_ParserTestCase());
$test->addTestCase(new Doctrine_BatchIteratorTestCase()); $test->addTestCase(new Doctrine_BatchIteratorTestCase());
/**
$test->addTestCase(new Doctrine_Cache_FileTestCase()); //$test->addTestCase(new Doctrine_Cache_FileTestCase());
$test->addTestCase(new Doctrine_Cache_SqliteTestCase()); //$test->addTestCase(new Doctrine_Cache_SqliteTestCase());
*/
...@@ -51,6 +52,16 @@ $test->addTestCase(new Doctrine_Cache_SqliteTestCase()); ...@@ -51,6 +52,16 @@ $test->addTestCase(new Doctrine_Cache_SqliteTestCase());
$test->run(new HtmlReporter()); $test->run(new HtmlReporter());
$cache = Doctrine_Manager::getInstance()->getCurrentSession()->getCacheHandler();
if(isset($cache)) {
$a = $cache->getQueries();
print "Executed cache queries: ".count($a)."\n";
/**
foreach($a as $query) {
print $query."\n";
}
*/
}
$dbh = Doctrine_Manager::getInstance()->getCurrentSession()->getDBH(); $dbh = Doctrine_Manager::getInstance()->getCurrentSession()->getDBH();
$a = $dbh->getQueries(); $a = $dbh->getQueries();
...@@ -58,7 +69,6 @@ $a = $dbh->getQueries(); ...@@ -58,7 +69,6 @@ $a = $dbh->getQueries();
print "Executed queries: ".count($a)."\n"; print "Executed queries: ".count($a)."\n";
foreach($a as $query) { foreach($a as $query) {
$e = explode(" ",$query);
print $query."\n"; print $query."\n";
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment