Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: Передача в функцию произвольного количества указателей

 PHP.SU

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


 Страниц (2): [1] 2 »   

> Без описания
Int_20h
Отправлено: 18 Июня, 2014 - 12:11:32
Post Id


Новичок


Покинул форум
Сообщений всего: 11
Дата рег-ции: Июнь 2014  


Помог: 0 раз(а)




Пытаюсь сделать обертку для функции mysqli_stmt_bind_param. Т.е. функцию вида

PHP:
скопировать код в буфер обмена
  1. function my_bind_param(){
  2.    $args = func_get_args();
  3.    $res = call_user_func_array('mysqli_stmt_bind_param', $args);
  4. }


Однако, как я понимаю, func_get_args() возвращает не указатели на параметры, переданные в функцию, а массив копий их значений, а значит bind в случае такой реализации будет не полноценный. Т.е. отрабатывать он будет только один раз, только с теми значениями, которые были переданы в функцию.

Я хочу сделать так, как в самом php, чтобы переменные именно биндились, т.е. работал вариант из документации:

PHP:
скопировать код в буфер обмена
  1. /* Prepare an insert statement */
  2. $query = "INSERT INTO myCity (Name, CountryCode, District) VALUES (?,?,?)";
  3. $stmt = $mysqli->prepare($query);
  4.  
  5. $stmt->bind_param("sss", $val1, $val2, $val3);
  6.  
  7. $val1 = 'Stuttgart';
  8. $val2 = 'DEU';
  9. $val3 = 'Baden-Wuerttemberg';
  10.  
  11. /* Execute the statement */
  12. $stmt->execute();
  13.  
  14. $val1 = 'Bordeaux';
  15. $val2 = 'FRA';
  16. $val3 = 'Aquitaine';
  17.  
  18. /* Execute the statement */
  19. $stmt->execute();
  20.  
  21. /* close statement */
  22. $stmt->close();


Отсюда вопрос. Как внутри функции получить список указателей на переданные параметры, если количество параметров может быть произвольным?
 
 Top
armancho7777777 Супермодератор
Отправлено: 18 Июня, 2014 - 13:14:30
Post Id



Активный участник


Покинул форум
Сообщений всего: 4526
Дата рег-ции: Февр. 2011  
Откуда: Москва


Помог: 221 раз(а)




PHP:
скопировать код в буфер обмена
  1. function my_bind_param()
  2. {
  3.     $args = func_get_args();
  4.     $bindArgs = array();
  5.    
  6.     foreach($args as $key => $val) {
  7.         $bindArgs[$key] =& $args[$key];
  8.     }
  9.    
  10.     $res = call_user_func_array('mysqli_stmt_bind_param', $bindArgs);
  11. }

?
 
 Top
LIME
Отправлено: 18 Июня, 2014 - 13:20:05
Post Id


Активный участник


Покинул форум
Сообщений всего: 10732
Дата рег-ции: Нояб. 2010  


Помог: 322 раз(а)




armancho7777777 смысл?

PHP:
скопировать код в буфер обмена
  1. function my_bind_param(ArgumentsCollection $args){
  2.    //...
  3. }

передавай объект...он по ссылке передается
(Добавление)
ну или массив по ссылке
PHP:
скопировать код в буфер обмена
  1. $args = [1, 2, 3];
  2. function my_bind_param(&$args){
  3.    //...
  4. }
 
 Top
armancho7777777 Супермодератор
Отправлено: 18 Июня, 2014 - 13:27:56
Post Id



Активный участник


Покинул форум
Сообщений всего: 4526
Дата рег-ции: Февр. 2011  
Откуда: Москва


Помог: 221 раз(а)




LIME пишет:
передавай объект

Куда ? В call_user_func_array ?
(Добавление)
LIME, а ты сам проверь для начала то, что предложил.
 
 Top
LIME
Отправлено: 18 Июня, 2014 - 13:30:13
Post Id


Активный участник


Покинул форум
Сообщений всего: 10732
Дата рег-ции: Нояб. 2010  


Помог: 322 раз(а)




PHP:
скопировать код в буфер обмена
  1. $res = call_user_func_array('mysqli_stmt_bind_param', (array) $argsCollection);

(Отредактировано автором: 18 Июня, 2014 - 13:30:33)

 
 Top
armancho7777777 Супермодератор
Отправлено: 18 Июня, 2014 - 13:32:16
Post Id



Активный участник


Покинул форум
Сообщений всего: 4526
Дата рег-ции: Февр. 2011  
Откуда: Москва


Помог: 221 раз(а)




Int_20h, mysqli_stmt_bind_param первым аргументом принимает строку - типы значений привязываемых переменных.

LIME пишет:
(array) $argsCollection

armancho7777777 пишет:
LIME, а ты сам проверь для начала то, что предложил.

(Отредактировано автором: 18 Июня, 2014 - 13:34:14)

 
 Top
LIME
Отправлено: 18 Июня, 2014 - 13:34:48
Post Id


Активный участник


Покинул форум
Сообщений всего: 10732
Дата рег-ции: Нояб. 2010  


Помог: 322 раз(а)




armancho7777777 зачем?
я указал как передавать параметры по ссылке
а как это будет использоваться вопрос второй
 
 Top
armancho7777777 Супермодератор
Отправлено: 18 Июня, 2014 - 13:39:29
Post Id



Активный участник


Покинул форум
Сообщений всего: 4526
Дата рег-ции: Февр. 2011  
Откуда: Москва


Помог: 221 раз(а)




LIME пишет:
я указал как передавать параметры по ссылке

С задачей ознакомься получше.
 
 Top
LIME
Отправлено: 18 Июня, 2014 - 13:40:57
Post Id


Активный участник


Покинул форум
Сообщений всего: 10732
Дата рег-ции: Нояб. 2010  


Помог: 322 раз(а)




ну
проблема что биндятся не передаваемые параметры а их копии
решения передавать по ссылке
а вот это вообще мне непонятно http://forum.php.su/topic.php?fo...86470#1403086470
 
 Top
armancho7777777 Супермодератор
Отправлено: 18 Июня, 2014 - 13:41:57
Post Id



Активный участник


Покинул форум
Сообщений всего: 4526
Дата рег-ции: Февр. 2011  
Откуда: Москва


Помог: 221 раз(а)




Всё, давай.
 
 Top
Int_20h
Отправлено: 18 Июня, 2014 - 13:50:19
Post Id


Новичок


Покинул форум
Сообщений всего: 11
Дата рег-ции: Июнь 2014  


Помог: 0 раз(а)




armancho7777777 пишет:
Всё, давай.


Lime, на самом деле, прав. То что предложил armancho7777777 конечно будет работать, но только один раз. Такого эффекта, как в исходном варианте - не будет.

PHP:
скопировать код в буфер обмена
  1.  
  2. $stmt->bind_param("sss", $val1, $val2, $val3);
  3.  
  4. $val1 = 'Stuttgart';
  5. $val2 = 'DEU';
  6. $val3 = 'Baden-Wuerttemberg';
  7.  
  8. /* Execute the statement */
  9. $stmt->execute();
  10.  
  11. $val1 = 'Bordeaux';
  12. $val2 = 'FRA';
  13. $val3 = 'Aquitaine';
  14.  
  15. /* Execute the statement */
  16. $stmt->execute();


Здесь bind_params вызывается один раз, а переменные используются 2 раза.
 
 Top
LIME
Отправлено: 18 Июня, 2014 - 13:56:25
Post Id


Активный участник


Покинул форум
Сообщений всего: 10732
Дата рег-ции: Нояб. 2010  


Помог: 322 раз(а)




во
не поленился
PHP:
скопировать код в буфер обмена
  1. function my_bind_param($stmt, $args){
  2.         array_unshift($args, 'sss');
  3.         array_unshift($args, $stmt);
  4.         call_user_func_array('mysqli_stmt_bind_param', $args);
  5. }
  6. $mysqli = new mysqli('localhost', 'root', 'bbahtk', 'kz');
  7. $query = "INSERT INTO new_table (new_tablecol, new_tablecol1, new_tablecol2) VALUES (?,?,?)";
  8. $stmt = $mysqli->prepare($query);
  9.  
  10.  
  11.  
  12. $args = [&$val1, &$val2, &$val3];
  13. my_bind_param($stmt, $args);
  14. /* Execute the statement */
  15.  
  16. $val1 = 'Stuttgart';
  17. $val2 = 'DEU';
  18. $val3 = 'Baden-Wuerttemberg';
  19.  
  20. $stmt->execute();
  21.  
  22. $val1 = 'Bordeaux';
  23. $val2 = 'FRA';
  24. $val3 = 'Aquitaine';
  25.  
  26. /* Execute the statement */
  27. $stmt->execute();

(Добавление)
а до 5.4 вообще можно передавать параметры по ссылке
теперь только в объявлении ф-ции можно
как-то так

(Отредактировано автором: 18 Июня, 2014 - 14:10:31)

 
 Top
armancho7777777 Супермодератор
Отправлено: 18 Июня, 2014 - 14:33:25
Post Id



Активный участник


Покинул форум
Сообщений всего: 4526
Дата рег-ции: Февр. 2011  
Откуда: Москва


Помог: 221 раз(а)




LIME пишет:
[&$val1, &$val2, &$val3]

armancho7777777 пишет:
foreach($args as $key => $val) {
        $bindArgs[$key] =& $args[$key];
    }

Всё тоже самое, за исключением того, что не надо ручками указывать ссылки.

Int_20h пишет:
То что предложил armancho7777777 конечно будет работать, но только один раз.

Из моего велика:
PHP:
скопировать код в буфер обмена
  1. class Statement {
  2.  
  3.     /**
  4.      * @var \mysqli_stmt
  5.      */
  6.     private $_stmt;
  7.  
  8.     /**
  9.      * @var string
  10.      */
  11.     private $_types = null;
  12.  
  13.  
  14.     public function __construct(\mysqli_stmt $stmt)
  15.     {
  16.         $this->_stmt = $stmt;
  17.     }
  18.  
  19.     /**
  20.      * @param array $types
  21.      * @return string
  22.      */
  23.     public function setTypes(array $types)
  24.     {
  25.         $this->_types = '';
  26.  
  27.         foreach($types as $type) {
  28.             if(preg_match('/^[idsb]$/', $type)) {
  29.                 $this->_types .= $type;
  30.             }
  31.         }
  32.  
  33.         return $this->_types;
  34.     }
  35.  
  36.     /**
  37.      * @param array $binds
  38.      * @return bool|\mysqli_result
  39.      */
  40.     public function exec(array $binds)
  41.     {
  42.         if(is_null($this->_types))
  43.         {
  44.             $this->_types = $this->setTypes(array_keys($binds));
  45.             $this->_types = str_pad(
  46.                 $this->_types, count($binds) - strlen($this->_types), 's'
  47.             );
  48.         }
  49.  
  50.         $params = array($this->_types);
  51.  
  52.         foreach($binds as $k => $v) {
  53.             $params[] =& $binds[$k];
  54.         }
  55.  
  56.         call_user_func_array(array($this->_stmt, 'bind_param'), $params);
  57.         $this->_stmt->execute();
  58.         return $this->_stmt->get_result();
  59.     }
  60.  
  61.     /**
  62.      * @param array $binds
  63.      * @param int $resultType
  64.      * @return array
  65.      */
  66.     public function fetchAll(array $binds, $resultType = MYSQL_ASSOC)
  67.     {
  68.         $exec = $this->exec($binds);
  69.         $result = array();
  70.  
  71.         while ($row = $exec->fetch_array(MYSQL_ASSOC)) {
  72.             $result[] = $row;
  73.         }
  74.  
  75.         return $result;
  76.     }
  77. }


Метод exec.

(Отредактировано автором: 18 Июня, 2014 - 15:38:13)

 
 Top
LIME
Отправлено: 18 Июня, 2014 - 14:51:09
Post Id


Активный участник


Покинул форум
Сообщений всего: 10732
Дата рег-ции: Нояб. 2010  


Помог: 322 раз(а)




у меня тоже не получается
Спойлер (Отобразить)
толи руки кривые
толи биндятся локальные копии в ф-ции
а через ссылки там или не через ссылки это ужо не суть
(Добавление)
пожалуй поясню
если в ф-цию передать переменную по значению то используется ее локальная копия
и она будет забиндена
и можно делать внутри ф-ции сколько угодно ссылок на нее это будут ссылки на локальную копию
и если изменить ее глобальный "прототип" то это никак не повлияет на локальную копию
которая впрочем все равно уничтожается после завершения ф-ции

(Отредактировано автором: 18 Июня, 2014 - 14:51:51)

 
 Top
armancho7777777 Супермодератор
Отправлено: 18 Июня, 2014 - 14:55:43
Post Id



Активный участник


Покинул форум
Сообщений всего: 4526
Дата рег-ции: Февр. 2011  
Откуда: Москва


Помог: 221 раз(а)




Блин...
Я не верно задачу понял )
А на хрена нужна такая "многословная" конструкция, Int_20h ?
Один раз вызвал функцию, а дальше биндишь...
Гм... Зачем, если можно сделать красивше ?

(Отредактировано автором: 18 Июня, 2014 - 15:39:28)

 
 Top
Страниц (2): [1] 2 »
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« Вопросы новичков »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB