PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи

Страниц (31): « 1 2 3 4 [5] 6 7 8 9 ... » В конец

> Найдено сообщений: 463
Prizma Отправлено: 15 Июня, 2016 - 01:31:41 • Тема: sql запрос • Форум: Вопросы новичков

Ответов: 0
Просмотров: 73
Есть три таблицы
products (id, cur_id, price)
actions (id, product_id, cur_id, price, start_time, finish_time)
currencies (id, rate)

Требует выбрать товары для которых существует действующая акционная цена.. и вроде всё просто:
CODE (SQL):
скопировать код в буфер обмена
  1. SELECT products.id FROM products, actions
  2. WHERE product.id = actions.product_id AND
  3.     actions.start_time < time() AND
  4.     actions.finish_time > time()


Однако из-за скачков курса некоторые акционные цены часто становятся выше начальной цены на сайте акционная цена скрывается если она выше нормальной цены. Нужен запрос который будет учитывать цену:

CODE (SQL):
скопировать код в буфер обмена
  1. SELECT products.id
  2. FROM products, actions, currencies
  3. WHERE product.id = actions.product_id AND
  4.     actions.start_time < time() AND
  5.     actions.finish_time > time() AND
  6.     products.cur_id = currencies.id AND
  7.     products.price * currencies.rate > actions.price * (X)


Если я сделаю подзапрос вместо X например:
(Х) =
CODE (SQL):
скопировать код в буфер обмена
  1. (SELECT currencies.rate FROM currencies WHERE currencies.cur_id = actions.cur_id)


То MySQL возвращает 0 строк в ответе без ошибок... Есть ли вариант одним запросом решить данную задачу?
(Добавление)
Помучался ещё немного и всё получилось Улыбка решил попробывать в рамках одного запроса вызывать одну таблицу несколько раз под разными псевдонимами.
CODE (SQL):
скопировать код в буфер обмена
  1. SELECT products.id
  2. FROM products, actions, currencies, currencies AS a_cur
  3. WHERE product.id = actions.product_id AND
  4.     actions.start_time < time() AND
  5.     actions.finish_time > time() AND
  6.     products.cur_id = currencies.id AND
  7.     a_cur.id = actions.currency_id AND
  8.     products.price * currencies.rate > actions.price * cur_a.rate
Prizma Отправлено: 18 Мая, 2016 - 13:19:35 • Тема: Наследование, и переопределение методов • Форум: Объектно-ориентированное программирование

Ответов: 10
Просмотров: 2299
armancho7777777 пишет:
(new B)->getY(); // B::calc

это уже перебор)) Зачем же я от него тогда наследовал класс A
armancho7777777 пишет:
Prizma
Если требуется, чтобы вызывался всегда метод A::calc,
то необходимо запретить переопределение метода в дочерних классах, объявив его финальным, как уже предложил Мелкий.

Метод B::calc() не может существовать без A::calc() но метод A::calc() так же используется внутри других методов класса A, и когда я начал обращаться к этим методам из класса B, то стал получать не корректные результаты потому, что там использовалось ключевое слово $this для вызова метода calc() и методы класса A стали использовать B::calc(), заменив $this->calc() на A::calc() в методах класса A, всё заработало, как должно Улыбка
Prizma Отправлено: 16 Мая, 2016 - 11:32:07 • Тема: Из каждого значения массива, отдельная переменная • Форум: Вопросы новичков

Ответов: 7
Просмотров: 281
manoftheyear пишет:
Допустим есть массив:
$array = array('one', 'two', 'three', 'four', 'five');

Как из каждого значения массива, сделать отдельную переменную? Имя переменных для значения неважно, хоть: val1, val2... valN.

PHP:
скопировать код в буфер обмена
  1. $array = array('one', 'two', 'three', 'four', 'five');
  2. $i = 0;
  3. foreach ($array as $val) {
  4.     $i++;
  5.     $name = 'val' . $i;
  6.     $$name = $val;
  7. }
  8. echo $val1; // one
  9. echo $val2; // two
  10. echo $val3; // three
  11. echo $val4; // four
  12. echo $val5; // five

(Добавление)
или так:
PHP:
скопировать код в буфер обмена
  1. foreach ($array as $val) {
  2.     $i++;
  3.     ${'val' . $i} = $val;
  4. }
Prizma Отправлено: 16 Мая, 2016 - 11:23:13 • Тема: Наследование, и переопределение методов • Форум: Объектно-ориентированное программирование

Ответов: 10
Просмотров: 2299
armancho7777777
то что надо, спасибо.

я подумал, что так только статик методы можно вызывать.
Prizma Отправлено: 16 Мая, 2016 - 10:35:30 • Тема: Наследование, и переопределение методов • Форум: Объектно-ориентированное программирование

Ответов: 10
Просмотров: 2299
Мелкий пишет:
Объявите calc как final.
Тогда я не смогу его переопределить, а это необходимо
Prizma Отправлено: 16 Мая, 2016 - 09:58:04 • Тема: Наследование, и переопределение методов • Форум: Объектно-ориентированное программирование

Ответов: 10
Просмотров: 2299
Добрый день,
вот такая ситуация сложилась во время разработки:
PHP:
скопировать код в буфер обмена
  1. class A{
  2.     public function getX()
  3.     {
  4.         return 'getX() - ' . $this->calc();
  5.     }
  6.  
  7.     protected function calc()
  8.     {
  9.         return 'A::calc()';
  10.     }
  11. }
  12.  
  13. class B extends A{
  14.     public function getY()
  15.     {
  16.         return 'getY() - ' . $this->calc();
  17.     }
  18.  
  19.     protected function calc()
  20.     {
  21.         return 'B=>' . parent::calc();
  22.     }
  23. }
  24.  
  25. $a = new A();
  26. var_dump($a->getX());
  27. $b = new B();
  28. var_dump($b->getX());
  29. var_dump($b->getY());
Результат:
Цитата:
string 'getX() - A::calc()' (length=18)
string 'getX() - B=>A::calc()' (length=21)
string 'getY() - B=>A::calc()' (length=21)

Проблема в некорректной работе метода getX() если вызывать его из класса B т.к. в нем переопределяется функция calc(). Существует ли ключевое слово для вызова из getX() A::calc() независимо от того был ли метод переопределен?

Пока вижу только такой вариант:
PHP:
скопировать код в буфер обмена
  1. class A{
  2.     public function getX()
  3.     {
  4.         return 'getX() - ' . $this->calc();
  5.     }
  6.  
  7.     protected function calc()
  8.     {
  9.         return $this->_calc();
  10.     }
  11.  
  12.     private function _calc()
  13.     {
  14.         return 'A::calc()';
  15.     }
  16. }
Prizma Отправлено: 05 Мая, 2016 - 00:58:08 • Тема: Битовые операции в Mysql • Форум: Вопросы новичков

Ответов: 0
Просмотров: 91
Почему бинарные операторы работают так непредсказуемо? разве не должен быть везде 0 для всех нечетных значений?

Собственно создание:
CODE (SQL):
скопировать код в буфер обмена
  1. CREATE TABLE `air_market_products` (
  2.  `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
  3. ...
  4.  `flags` bigint(20) UNSIGNED NOT NULL,
  5. ) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=utf8


Есть куча параметров:
public, delivery, in_stock, look_price, look_producer и другие... Нужно сделать выборку из таблицы тех товаров которые будут соответствовать всем флагам.

Решил проверить в phpmyadmin на всякий случай и результат меня печально удивил.

скрин результата в приложении

Mysql-5.6-x64
(Добавление)
CODE (SQL):
скопировать код в буфер обмена
  1. SELECT 999998 & 2, 999999 & 2
собственно и там и там выдает, как результат 2, хотя во втором случае я ожидал ноль Недовольство, огорчение
(Добавление)
Ребят, отбой... это у меня мозги поплыли... надо спать идти Улыбка дурак каюсь...
Prizma Отправлено: 25 Апреля, 2016 - 00:31:10 • Тема: PHP 7 Использование контроля скалярных типов • Форум: Объектно-ориентированное программирование

Ответов: 28
Просмотров: 4537
И так провел воскресенье, вдаваясь в тонкости ООП и разбирая несколько примеров, и вот, что получилось:
PHP:
скопировать код в буфер обмена
  1. interface IProductsSource
  2. {
  3.     const LOAD_BRIEF_INFO = 1;
  4.     const LOAD_GENERAL_INFO = 2;
  5.     const LOAD_FULL_INFO = 3;
  6.  
  7.     /**
  8.      * @param array $productsId
  9.      * @param int $mode
  10.      * @return array [id=>Product]
  11.      */
  12.     public function load(array $productsId, int $mode) : array;
  13.  
  14.     public function update(Product $product) : bool;
  15.  
  16.     public function delete(Product $product) : bool;
  17. }
  18.  
  19.  
  20. class MysqlIProductsSource implements IProductsSource
  21. {
  22.     use Mysql;
  23.    
  24.     public function load(array $productsId, int $mode) : array
  25.     {
  26.         if(empty($productsId)) {
  27.             return [];
  28.         }
  29.         foreach ($productsId as &$id) {
  30.             if (is_string($id)) {
  31.                 $id *= 1;
  32.             } elseif (!is_int($id)) {
  33.                 throw new \InvalidArgumentException('$productsId');
  34.             }
  35.         }
  36.         $in = implode(',', $productsId);
  37.         $fields = [];
  38.         switch($mode) {
  39.             case self::LOAD_FULL_INFO:
  40.                 $fields[] = 'description';
  41.                 // no break
  42.             case self::LOAD_GENERAL_INFO:
  43.                 $fields[] = 'producer_id, author_id, currency_id, price, in_stock_amount, delivery_days, short_desc,'.
  44.                     'seo_desc, seo_kw, created, modified, obj_properties';
  45.                 // no break
  46.             case self::LOAD_BRIEF_INFO:
  47.                 $fields[] = 'id, name';
  48.                 break;
  49.             default:
  50.                 throw new \InvalidArgumentException('$mode');
  51.         }
  52.         $fields = implode(',', $fields);
  53.         $sql = 'SELECT '.$fields.' FROM '.MTables::PRODUCTS.' WHERE id IN('.$in.');';
  54.         $re = [];
  55.         $q = self::db()->prepare($sql);
  56.         $q->execute();
  57.         while($r = $q->fetch(\PDO::FETCH_ASSOC)) {
  58.             $re[$r['id']] = new Product($r);
  59.         }
  60.         return $re;
  61.     }
  62.  
  63.     public function update(Product $product) : bool
  64.     {
  65.         // TODO: Implement update() method.
  66.         return false;
  67.     }
  68.  
  69.     public function delete(Product $product) : bool
  70.     {
  71.         // TODO: Implement delete() method.
  72.         return false;
  73.     }
  74.  
  75. }
  76.  
  77.  
  78. class ProductRepository
  79. {
  80.     /** @var IProductsSource */
  81.     private $source;
  82.  
  83.     public function __construct(IProductsSource $source)
  84.     {
  85.         $this->setSource($source);
  86.     }
  87.  
  88.     public function setSource(IProductsSource $source)
  89.     {
  90.         $this->source = $source;
  91.     }
  92.    
  93.     /**
  94.      * @param array $productsId
  95.      * @param int $mode
  96.      * @return array [id=>Product]
  97.      */
  98.     public function load(array $productsId, int $mode) : array
  99.     {
  100.         return $this->source->load($productsId, $mode);
  101.     }
  102.  
  103.     public function update(Product $product) : bool
  104.     {
  105.         return $this->source->update($product);
  106.     }
  107.  
  108.     public function delete(Product $product) : bool
  109.     {
  110.         return $this->source->delete($product);
  111.     }
  112. }
  113.  
  114.  
  115. class Product
  116. {
  117.     /* @var int */
  118.     private $id;
  119.     /* @var int */
  120.     private $producerId;
  121.     /* ... */
  122.  
  123.     public function __construct(array $source)
  124.     {
  125.         foreach ($source as $key => $value) {
  126.             $this->$key = $value;
  127.         }
  128.     }
  129.        
  130.     public function getId() : int {/* ... */}
  131.     /* and another getters... */
  132. }
  133.  
  134.  
  135. /* EXAMPLE */
  136.  
  137. $re = new ProductRepository(new MysqlIProductsSource());
  138. $products = $re->load([1, 2, 46, 58], IProductsSource::LOAD_GENERAL_INFO);
  139. foreach ($products as $product) {
  140.     echo $product->getName();
  141. }

Как то так.. Для хранения экземпляров класса Product ничего лучше массива не приудмал, хотя была мысль сделать ProductList, даже написал его, но в итоге не понял в чем принципиальная разница от простого массива... разве, что добавить туда методы updateAll, deleteAll которые мне пока точно не нужны. Хотя смотря в будущее возможно всё таки к этому еще вернусь, когда буду переписывать корзину товаров, там и общая стоимость всех товаров и скидка в от суммы заказа тоже зависит...

Данные перед выходом нужно обработать (именно сами данные): перевести цены в рубли, расчитать кол-во дней до конца акции, пропарсить описание на предмет подстановки... (это те функции, которые уже реализованы на сайте, а я собственно решил переписать свой код 2-ух летней давности, со свежим взглядом). Если я правильно начинаю понимать ООП, это именно те методы, которые должны быть реализованы в классе Product?
(Добавление)
еще подумываю в геттерах класса Product генерировать ошибку в случае запроса атрибута со значением равным null (т.е. те которые не определены в выбранном режиме).
Prizma Отправлено: 24 Апреля, 2016 - 21:12:04 • Тема: PHPStorm case \\ no break • Форум: Вопросы новичков

Ответов: 0
Просмотров: 98
Добрый день,
вопрос по IDE PHPStorm, предусмотрен ли там, какой то комментарий для обозначения преднамеренного падения в switch? чтобы не подсвечивал код. Не хотелось бы эту опцию для проекта отключать
PHP:
скопировать код в буфер обмена
  1. switch($mode) {
  2.     case self::LOAD_FULL_INFO:
  3.         $fields[] = '...';
  4.     // no break
  5.     case self::LOAD_GENERAL_INFO:
  6.         $fields[] = '...';
  7.     // no break
  8.     case self::LOAD_BRIEF_INFO:
  9.         $fields[] = '...';
  10. }

(Добавление)
Нашел вот такой способ
PHP:
скопировать код в буфер обмена
  1. switch($mode) {
  2.     /** @noinspection PhpMissingBreakStatementInspection */
  3.     case self::LOAD_FULL_INFO:
  4.         $fields[] = 'description';
  5.     // no break
  6.     /** @noinspection PhpMissingBreakStatementInspection */
  7.     case self::LOAD_GENERAL_INFO:
  8.         $fields[] = 'producer_id, author_id, currency_id, price, in_stock_amount, delivery_days, short_desc,'.
  9.             'seo_desc, seo_kw, created, modified, obj_properties';
  10.     case self::LOAD_BRIEF_INFO:
  11.         $fields[] = 'id, name';
  12. }
Prizma Отправлено: 24 Апреля, 2016 - 18:11:37 • Тема: PHP 7 Использование контроля скалярных типов • Форум: Объектно-ориентированное программирование

Ответов: 28
Просмотров: 4537
LIME пишет:
Просто если таких параметров 15-20, окей пилю в аргумент массив или объект, получается массив полученный от $q->fetch(...) идет в аргумент, а чем статический create будет лучше стандартного __construct($name, $price)?
teddy пишет:
Так у вас будет 2 цикла. Один заполнение массива, другой - для вывода данных из этого массива(через объекты которые в этом массиве). Тут явно напрашивается Traversable.
Согласен - расточительно. Почитал про итераторы.. т.е. реализовать класс class productList implements Iterator для этого дела? и помимо обязательных методов описанных интерфейсом, методы добавление удаления типа addItem, removeItem так?
Prizma Отправлено: 24 Апреля, 2016 - 17:01:14 • Тема: PHP 7 Использование контроля скалярных типов • Форум: Объектно-ориентированное программирование

Ответов: 28
Просмотров: 4537
Я определился, что мне нужно. Мне нужен класс Product как хранилище... я решил разделить его на 3 класса:
ProductBreifInfo (содержит только 2 поля - имя и id)
ProductGeneralInfo extends ProductBreifInfo (добавляются дополнительные поля)
ProductFullIngo extends ProductGeneralInfo (добавляются редко используемые тяжелые текстовые поля)
не уверен стоило ли делать так или просто оставлять не сообщенные поля пустыми.

По реализации заполнения классов у меня появилось 2 варианта
Вариант 1 (на примере первого класса):
PHP:
скопировать код в буфер обмена
  1. class ProductBreifInfo
  2. {
  3.     /* @var int */
  4.     private $id;
  5.     /* @var string */
  6.     private $name;
  7.  
  8.     public function getId() : int
  9.     {
  10.         return $this->id;
  11.     }
  12.    
  13.     public function setId(int $id) : void
  14.     {
  15.         $this->id = $id;
  16.     }
  17.  
  18.     public function getName() : string
  19.     {
  20.         return $this->name;
  21.     }
  22.  
  23.     public function setName(string $name) : void
  24.     {
  25.         $this->name = $name;
  26.     }
  27. }
  28.  
  29. $products = [];
  30. $q = $db->prepare('SELECT id, name FROM products');
  31. $q->execute();
  32. while($r = $q->fetch(PDO::FETCH_ASSOC)) {
  33.     $product = new ProductBreifInfo();
  34.     $product->setId($r['id']);
  35.     $product->setName($r['name']);
  36.     $products[$product->getId()] = $product;
  37. }

Вариант 2 (на примере первого класса):
PHP:
скопировать код в буфер обмена
  1. class ProductBreifInfo
  2. {
  3.     /* @var int */
  4.     private $id;
  5.     /* @var string */
  6.     private $name;
  7.    
  8.     public function __construct($source)
  9.     {
  10.         foreach ($source as $v => $k) {
  11.             if(!isset($this->$k)) {
  12.                 throw new \InvalidArgumentException();
  13.             }
  14.             $this->$k = $v;
  15.         }
  16.     }
  17.  
  18.     public function getId() : int
  19.     {
  20.         return $this->id;
  21.     }
  22.  
  23.     public function getName() : string
  24.     {
  25.         return $this->name;
  26.     }
  27. }
  28.  
  29. $products = [];
  30. $q = $db->prepare('SELECT id, name FROM products');
  31. $q->execute();
  32. while($r = $q->fetchObject("ProductBreifInfo")) {
  33.     $product = new ProductBreifInfo($r);
  34.     $products[$product->getId()] = $product;
  35. }

Первый вариант мне кажется топорным. Второй вариант мне нравится больше, только, тогда вопрос - а стоит ли разделять класс Product - пусть есть пустые поля, они же не мешают, всегда если надо можно добавить недостающие в старый экземпляр, а не грузить всё заново.
Prizma Отправлено: 24 Апреля, 2016 - 11:55:19 • Тема: PHP 7 Использование контроля скалярных типов • Форум: Объектно-ориентированное программирование

Ответов: 28
Просмотров: 4537
teddy пишет:
Это кто сказал? Причины в студию, пруф, что это всегда зло. Нужно использовать, но с умом. А вообще выстрелить в ногу можно всякими инструментами, даже полезными, если разработчик плохо понимает с чем имеет дело.

teddy пишет:
По поводу "Сетеры это лишнее знание для клиентского кода", в данном случае это очень удобно. Но да, остается возможность переопределить значение "прямым" обращением, инкапсуляция и все такое... Эту возможность можно "прикрыть" простой проверкой в __set.

Причин много даже для меня:
1. Код становится менее понятным и в случае нагруженности set, менее предсказуемым
2. IDE не сможет тебе помогать (не в данном случае, тут переменные будут браться через getVar), однако если определять их в не PDO, то будет ругаться, на их область видимости.
3. Любые изменения названия полей в бд, вытекут в сложно диагностируемую ошибку, можно конечно добавить в __set проверку, что если не существует генерировать предупреждение, но зачем создавать такую почву?
4. Есть другие способы более элегантные, по реализации.
5. Сколько я в своей практике не использовал __set рано или поздно приходил, к тому, что эту часть кода приходилось переписывать, либо постоянно модифицировать.
LIME пишет:
Prizma топаешь в нужном направлении... так держать
Еще grasp
Если дядюшку Мартина асилишь
книжка интересная, по GRASP надеюсь, тоже в ближайшее время доберусь ...

Спасибо за советы.
Prizma Отправлено: 24 Апреля, 2016 - 00:18:44 • Тема: PHP 7 Использование контроля скалярных типов • Форум: Объектно-ориентированное программирование

Ответов: 28
Просмотров: 4537
Интересные вы обсуждения ведёте, однако магические методы точно использовать не хорошо..
teddy пишет:
$products = $dbh->query('SELECT name, price FROM products');
$products->setFetchMode(PDO::FETCH_CLASS, 'Product');
Этот код не полный там не хватает наверно execute... чтобы он работал
Однако всё равно не думаю, что стоит пользоваться этим механизмом PDO, если он требует public переменные или __set ... начал читать одну из книжек по ООП "Быстрая разработка программ" от Роберта Мартина, пошарил по интернету...

Еще точно не определился, как именно реализую этот класс, времени не было, но завтра отпишу, что получилось.

PS: не думал, что может быть так сложно правильно реализовать достаточно простой класс, следуя всем принципам ООП. Однако, почитав немного поглубже про принципы, шаблоны... понял, что моё понимание было достаточно узким и не полным относительно этих принципов и ООП в целом.
Prizma Отправлено: 22 Апреля, 2016 - 21:17:30 • Тема: PHP 7 Использование контроля скалярных типов • Форум: Объектно-ориентированное программирование

Ответов: 28
Просмотров: 4537
Мелкий пишет:
В каждом (каждом!) PHP-файле.

в каждом вызываемом Вы имеете ввиду или в файле каждого класса который инклюдится тоже?
(Добавление)
По поводу SOLID нашел прекрасную статью на хабре https://habrahabr[dot]ru/post/208442/ там конечно в кратце, но начальное понимание дает... пойду читать, искать материал. Подумаю над лучшей реализацией.

Спасибо за советы, если будут еще комментарии обязательно прочитаю.
Prizma Отправлено: 22 Апреля, 2016 - 20:29:23 • Тема: PHP 7 Использование контроля скалярных типов • Форум: Объектно-ориентированное программирование

Ответов: 28
Просмотров: 4537
teddy пишет:
А должны быть. Может все таки не включен? Или у нас разные понятия о строгом режиме...

PHP:
скопировать код в буфер обмена
  1. error_reporting(E_STRICT);
  2. ini_set('error_reporting', E_ALL);
  3. ini_set('display_errors', 1);
  4. ini_set('display_startup_errors', 1);

этого мало? нет ошибок могу архив с бд и кодом залить.. экземпляр создается, все параметры доступны, ошибок нет
(Добавление)
teddy пишет:
У вас метод issetProduct не статичный, соответственно экземпляр вы создаете в любом случае, лишь с той разницей, что бросаете исключение если продукт не нашелся в БД. Не нужно себя обманывать. Кроме того, Product никак не должен брать на себя за подобную ответственность. Ничего не мешает сделать проверку по идентификатору вне Product и там же определить, надо ли создавать экземпляр.
Это опечатка, естественно я имел ввиду, что он будет статичный.
(Добавление)
Prizma пишет:
Это опечатка, естественно я имел ввиду, что он будет статичный.
поправил
(Добавление)
добавил код трейта Mysql, может еще какие ошибки увидите))

Страниц (31): « 1 2 3 4 [5] 6 7 8 9 ... » В конец
Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB