указатель кинул значит это, нужен ещё списочный vector и строковый string для полноты картины ааа string есть уже? =)))
Костян http://php.net/arrayobject по скорости сопоставим с родным array() и много быстрее любых самопальных.
Просто не углубляйся в те мелочи, которые уже реализованы в самом языке. (если, конечно, ты не пишешь учебник по программированию) Того же контроллера - нет. Можешь описать свой DBAL, а можешь и ORM. Архитектуру модулей, плагинов - общее апи расширений. Точки входа или эвенты. Лично мне сейчас интересны кодогенераторы. Вобщем писать в мануал всегда есть что. Было бы желание
ну так как я привел пример шаблона проектирования итератор как бы, то наверно я все же допишу в конце, что это всё может ArrayObject...
!!! PHP: <? $cities_id=array(1,2,3,4,5,6); $cities_name=array("MSK","SPB","NN","KZ","NOV","UFA"); GHTML::Run(array("html_autoinsert_on"=>0,"html_method"=>"_POST")); print GHTML::Link("/test.php",null,GHTML::Link("/test.php")->Html("<b>[Главная]</b>"))->Html("[Главная]"); print " "; print GHTML::Link("/test.php?act=reg",null,GHTML::Link("/test.php?act=reg")->Html("<b>[Регистрация]</b>"))->Html("[регистрация]"); print GHTML::Form("POST","") ->HTML( GHTML::Input("name","text","Имя пользователя",null,true)->Html(), "<br>", GHTML::Input("pass1","password","Пароль")->Html(), "<br>", GHTML::Input("pass2","password","Пароль ещё раз")->Html(), "<br>", GHTML::Select("city")->Html( GHTML::Option("")->Html("Выберите город"), GHTML::Option($cities_id,$_POST['city'])->Html($cities_name) ), "<br>", GHTML::Textarea("resume",50,9,null,true)->Html("Ненмого о себе"), "<br>", GHTML::Input("","submit","Жми!")->Html() ); ?> HTML: <a href='/test.php' />[Главная]</a> <a href='/test.php?act=reg' /><b>[Регистрация]</b></a>[регистрация]<form method='POST' action='' /><input type='text' name='name' value='Имя пользователя' /><br><input type='password' name='pass1' value='Пароль' /><br><input type='password' name='pass2' value='Пароль ещё раз' /><br><select name='city' /><option value='' />Выберите город</option><option value='6' />MSK</option><option value='5' />SPB</option><option value='4' />NN</option><option value='3' />KZ</option><option value='2' />NOV</option><option value='1' />UFA</option></select><br><textarea name='resume' cols='50' rows='9' />Ненмого о себе</textarea><br><input type='submit' name='' value='Жми!' /></form> Костян бери на заметку
$arr[0]=!empty($arr[0])?$arr[0]:null; =) я делал чтоб ссылочки рисовать а потом понесло =) ещё можно как кешер значений полей юзать. но у меня есть FormCacher с регулярками
Не. Вот например такое. PHP: <?php /** * Generate code for models * */ public function modelAction() { if ($this->_request->isPost()) { $db = Zend_Db_Table_Abstract::getDefaultAdapter(); $generatedModels = array(); $sqlTables = 'show tables'; $res = $db->query($sqlTables); $tables = $res->fetchAll(); /** * Iterate tables */ foreach($tables as $row) { $tableName = current($row); $modelFileName = $this->_getModelFileNameByTableName($tableName); $modelMapperFileName = $this->_getModelMapperFileNameByTableName($tableName); $modelClassName = $this->_getModelClassNameByTableName($tableName); $modelMapperClassName = $this->_getModelMapperClassNameByTableName($tableName); /** * model */ $modelFile = new Zend_CodeGenerator_Php_File(); $modelMapperFile = new Zend_CodeGenerator_Php_File(); $_fields = new Zend_CodeGenerator_Php_Property(); $_tableClass = new Zend_CodeGenerator_Php_Property(); $_constructor = new Zend_CodeGenerator_Php_Method(); /** * mapper */ $modelClass = new Zend_CodeGenerator_Php_Class(); $modelMapperClass = new Zend_CodeGenerator_Php_Class(); $_name = new Zend_CodeGenerator_Php_Property(); $_rowClass = new Zend_CodeGenerator_Php_Property(); /** * docblocks */ $modelMapperDocBlock = Zend_CodeGenerator_Php_Docblock::fromReflection( new Zend_Reflection_Docblock( $this->_getClassDocBlock($modelMapperClassName))); $modelDocBlock = Zend_CodeGenerator_Php_Docblock::fromReflection( new Zend_Reflection_Docblock( $this->_getClassDocBlock($modelClassName))); /** * $_name for MapperClass */ $_name->setName('_name') ->setVisibility(Zend_CodeGenerator_Php_Member_Abstract::VISIBILITY_PROTECTED) ->setDefaultValue($tableName); $sqlFields = 'SHOW COLUMNS FROM ' . $tableName; $resultFields = $db->query($sqlFields)->fetchAll(); /** * Get list of table fields */ $fields = array(); $fieldsDocBlock = array(); foreach($resultFields as $fieldInfo) { $fields[$fieldInfo['Field']] = null; $fieldsDocBlock[] = Zend_CodeGenerator_Php_Docblock_Tag::factory( 'property')->setDescription($fieldInfo['Type'] . ' $' . $fieldInfo['Field']); } $modelDocBlock->setTags($fieldsDocBlock); $modelDocBlock->setSourceDirty(); $fileDocBlock = Zend_CodeGenerator_Php_Docblock::fromReflection( new Zend_Reflection_Docblock( $this->_getFileDocBlock())); $_fields->setName('_data') ->setVisibility(Zend_CodeGenerator_Php_Member_Abstract::VISIBILITY_PROTECTED) ->setDefaultValue($fields); $_tableClass->setName('_tableClass') ->setVisibility(Zend_CodeGenerator_Php_Member_Abstract::VISIBILITY_PROTECTED) ->setDefaultValue($modelMapperClassName); // $constructorParam = new Zend_CodeGenerator_Php_Parameter(); // $constructorParam->setName('config') // ->setDefaultValue(array()); // // /** // * If no mapper passed then init model with standart Zend_Db_Table // */ // $constructorBody = 'if (!isset($config["table"])) {' // . PHP_EOL // . ' $this->setTable(new Zend_Db_Table(\'' . $name . '\'));' // . PHP_EOL // . ' $config["table"] = $this->_table;' // . PHP_EOL // . '}' // . PHP_EOL // . 'parent::__construct($config);'; // // $_constructor->setName('__construct') // ->setParameter($constructorParam) // ->setVisibility(Zend_CodeGenerator_Php_Member_Abstract::VISIBILITY_PUBLIC) // ->setBody($constructorBody); $_rowClass->setName('_rowClass') ->setVisibility(Zend_CodeGenerator_Php_Member_Abstract::VISIBILITY_PROTECTED) ->setDefaultValue($modelClassName); /** * build model mapper class */ $modelMapperClass->setName($modelMapperClassName) ->setProperty($_name) ->setProperty($_rowClass) ->setExtendedClass(CodegenController::modelPrefix . 'Mapper_Abstract'); $modelMapperClass->setDocblock($modelMapperDocBlock); /** * build class with method and properties */ $modelClass->setName($modelClassName) ->setProperty($_fields) ->setProperty($_tableClass) ->setExtendedClass(CodegenController::modelPrefix . 'Abstract'); // ->setMethod($_constructor); $modelClass->setDocblock($modelDocBlock); /** * build model */ $modelFile->setFilename($modelFileName); $modelFile->setClass($modelClass); $modelFile->setDocblock($fileDocBlock); $modelFile->write(); /** * build model mapper */ $modelMapperFile->setFilename($modelMapperFileName); $modelMapperFile->setClass($modelMapperClass); $modelMapperFile->setDocblock($fileDocBlock); $modelMapperFile->write(); $generatedModels[$modelClassName] = array($modelFileName, $modelMapperFileName); } $this->view->generatedModels = $generatedModels; } } /** * Generate relations for models * */ public function relationAction() { if ($this->_request->isPost()) { $db = Zend_Db_Table::getDefaultAdapter(); $generatedRelations = array(); foreach (glob($this->_modelsPath . 'mappers/*.php') as $fileName) { require_once $fileName; $reflection = new Zend_Reflection_File($fileName); $class = $reflection->getClass(); /** * Modify models except Final, Abstract and Interface */ if (! $class->isFinal() && $class->isInstantiable() && $class->isSubclassOf('Zend_Db_Table_Abstract') ) { /* @var $codeGen Zend_CodeGenerator_Php_Class */ $codeGen = Zend_CodeGenerator_Php_File::fromReflection($reflection); $codeGen->setFilename($fileName); $codeGenClass = $codeGen->getClass(); /* @var $doc Zend_Reflection_Docblock|ReflectionClass */ $doc = $codeGenClass->getDocblock(); /* @var $rowObject Model_Abstract */ $rowObject = $class->newInstance(); $tableName = $rowObject->info('name'); $createTable = $db->query('SHOW CREATE TABLE ' . $db->quoteIdentifier($tableName))->fetchAll(); $tmp = implode('', current($createTable)); $result = array(); // no DB constraints $refMap = array(); if (strpos($tmp, 'CONSTRAINT') === false) { // no DB constraints } else { $matches = array(); $res = preg_match_all('~FOREIGN\s+KEY\s+(?:\(`(\w+)+`\))+\s+REFERENCES\s+(?:`(\w+)+`)+\s+(?:\(`(\w+)+`\))+~', $tmp, $matches); if ($res) { $result = array(); /* * $matches[1] list of constraints * $matches[2] list of related tables * $matches[3] list of related fields */ foreach($matches[1] as $mkey => $srcCol) { $result[$srcCol] = array($matches[2][$mkey] => $matches[3][$mkey]); $refMap[$srcCol] = array( 'columns' => $srcCol, 'refTableClass' => $this->_getModelMapperClassNameByTableName($matches[2][$mkey]), 'refColumns' => $matches[3][$mkey] ); } } } // $tags = $doc->getTags(); // /* @var $tag Zend_CodeGenerator_Php_Docblock_Tag */ // foreach($tags as $tag) { // if ($tag->getName() == 'property') { // $desc = $tag->getDescription(); // list($type, $var) = explode(' ', $desc); // $key = substr($var, 1); // if (array_key_exists($key, $result)) { // $relatedModel = $this->_getModelClassNameByTableName(key($result[$key])) . '|'; // $tag->setDescription($relatedModel . $type . ' ' . $var); // } // } // } // $doc->setSourceDirty(); $_referenceMap = $codeGenClass->getProperty('_referenceMap'); if (!$_referenceMap) { $_referenceMap = new Zend_CodeGenerator_Php_Property(); $codeGenClass->setProperty($_referenceMap); } $_referenceMap->setDefaultValue($refMap) ->setVisibility(Zend_CodeGenerator_Php_Member_Abstract::VISIBILITY_PROTECTED) ->setName('_referenceMap'); $codeGenClass->setSourceDirty(); /* @var $codeGen Zend_CodeGenerator_Php_File */ $codeGen->write(); $generatedRelations[$codeGenClass->getName()] = $refMap; } } $this->view->generatedRelations = $generatedRelations; } } И на выходе 50 классов. Такого типа PHP: <?php /** * Description of Model_Offer * * @property int(11) $id * @property int(11) $type * @property int(11) $source * @property int(11) $target * @property date $dates * @property date $datee * @property int(11) $subject * @property int(11) $object * @property varchar(200) $src_desc * @property varchar(200) $trg_desc * @property int(11) $status * @property decimal(16,4) $price * @property int(11) $currency * @property int(11) $user_id * @property datetime $created */ class Model_Offer extends Model_Abstract { protected $_data = array( 'id' => null, 'type' => null, 'source' => null, 'target' => null, 'dates' => null, 'datee' => null, 'subject' => null, 'object' => null, 'src_desc' => null, 'trg_desc' => null, 'status' => null, 'price' => null, 'currency' => null, 'user_id' => null, 'created' => null ); protected $_tableClass = 'Model_Mapper_Offer'; } PHP: <?php /** * * Description of Model_Mapper_Offer * */ class Model_Mapper_Offer extends Model_Mapper_Abstract { protected $_name = 'offer'; protected $_rowClass = 'Model_Offer'; protected $_referenceMap = array( 'source' => array( 'columns' => 'source', 'refTableClass' => 'Model_Mapper_City', 'refColumns' => 'id' ), 'target' => array( 'columns' => 'target', 'refTableClass' => 'Model_Mapper_City', 'refColumns' => 'id' ), 'subject' => array( 'columns' => 'subject', 'refTableClass' => 'Model_Mapper_Location', 'refColumns' => 'id' ), 'status' => array( 'columns' => 'status', 'refTableClass' => 'Model_Mapper_OfferStatus', 'refColumns' => 'id' ), 'currency' => array( 'columns' => 'currency', 'refTableClass' => 'Model_Mapper_Currency', 'refColumns' => 'id' ), 'object' => array( 'columns' => 'object', 'refTableClass' => 'Model_Mapper_Item', 'refColumns' => 'id' ), 'type' => array( 'columns' => 'type', 'refTableClass' => 'Model_Mapper_OfferType', 'refColumns' => 'id' ), 'user_id' => array( 'columns' => 'user_id', 'refTableClass' => 'Model_Mapper_User', 'refColumns' => 'id' ) ); } И работать с ними можно потом вот так PHP: <?php $table = new Model_Mapper_City(); echo '<h1>Get city #1</h1>'; $city = $table->find(1)->current(); var_dump($mdl->toArray()); echo '<hr/><h1>Get country by city</h1>'; /* @var $country Zend_Db_Table_Row_Abstract */ $country = $city->findParentModel_Mapper_CountryBycountry_id(); var_dump($country->toArray()); echo '<hr/><h1>Get cities by country</h1>'; var_dump($country->findDependentRowset('Model_Mapper_City')->toArray());
? Я хомячков не боюсь Зачем? У меня было все тоже самое Только написанное без него Как результат - мы подумали, и я решил Что на этом уровне меня его реализация устраивает с небольшой оберткой. Мои модели работали примерно так PHP: <?php $mp = new Offer(); $mdl = $mp->find(1); print_r($mdl); // object(Offer) [123] protected _data => array( 'id' => 1, 'user_id' => 2, ... echo $mdl->id; // 1 echo $mdl->user_id; // Vasya echo $mdl->user_id->id; // 2 print_r($mdl->findOffer('user_id')); // array(1 => object(Offer) [124] ... , 17 => object(Offer) [125] ... ) print_r($mdl->user_id->findOffer()); // array(1 => object(Offer) [126] ... , 17 => object(Offer) [127] ... ) Только на их написание я угробил неделю, а на ZF практически такой же результат я получил за 1 день. Почувствуйте разницу.
ты сам знаешь что спорить о почутвуйте разницу, безполезно это как, я писал шаблонизатор 3 часа, а потом взял смарти и получил шаблонизатор и кучу всякого ненужного говна на одну минуту =) зачем? вот хотя бы поэтому =) PHP: class Model_Mapper_Offer extends Model_Mapper_Abstract { protected $_name = 'offer'; protected $_rowClass = 'Model_Offer'; protected $_referenceMap = array( 'source' => array( 'columns' => 'source', 'refTableClass' => 'Model_Mapper_City', 'refColumns' => 'id' ), 'target' => array( 'columns' => 'target', 'refTableClass' => 'Model_Mapper_City', 'refColumns' => 'id' ), 'subject' => array( 'columns' => 'subject', 'refTableClass' => 'Model_Mapper_Location', 'refColumns' => 'id' ), 'status' => array( 'columns' => 'status', 'refTableClass' => 'Model_Mapper_OfferStatus', 'refColumns' => 'id' ), 'currency' => array( 'columns' => 'currency', 'refTableClass' => 'Model_Mapper_Currency', 'refColumns' => 'id' ), 'object' => array( 'columns' => 'object', 'refTableClass' => 'Model_Mapper_Item', 'refColumns' => 'id' ), 'type' => array( 'columns' => 'type', 'refTableClass' => 'Model_Mapper_OfferType', 'refColumns' => 'id' ), 'user_id' => array( 'columns' => 'user_id', 'refTableClass' => 'Model_Mapper_User', 'refColumns' => 'id' ) ); } я хз как ты там писал, но компов тебе понадобиться много =)