Перейти к содержимому


Изучаем php :)


  • Вы не можете ответить в тему
Сообщений в теме: 23

#1 R.Sergey

    Администратор

  • Администраторы
  • 2810 сообщений
Репутация: 332
Мастер

Отправлено 10 January 2012 - 01:49 PM

Вопрос к профи php
наткнулся на оператор !emptyempty никак не могу найти описание синтаксиса - что он делает собственно и как его использовать может кто-нибудь подсказать?
  • 0

#2 badisoft

    Продвинутый пользователь

  • Assistent vsupport.club
  • PipPipPip
  • 5075 сообщений
Репутация: 786
Мастер

Отправлено 10 January 2012 - 03:26 PM

Вот, например.
Там человек удивляется, почему он постит в форму empty, а оно потом удваивается.
  • 0
http://cpu.badisoft.ru (тестовый сайт), http://badisoft.ru (модули)

#3 R.Sergey

    Администратор

  • Администраторы
  • 2810 сообщений
Репутация: 332
Мастер

Отправлено 10 January 2012 - 06:42 PM

Там человек удивляется, почему он постит в форму empty, а оно потом удваивается.

да действительно удивляется, вот и я удивляюсь т.к. встретил эту конструкцию не один раз НО каждый раз это цитата кода, а в описании только empty(). Скорее всего ты прав. Спасибо(!!!)... а я мозг сломал - ну что это может значить....
  • 0

#4 R.Sergey

    Администратор

  • Администраторы
  • 2810 сообщений
Репутация: 332
Мастер

Отправлено 30 April 2012 - 08:52 PM

Еще одна проблемка возникла.
Пишу инсталлятор полуавтоматический для одного модуля, что он собственно делает

Открывает файл пхп только для чтения
$file = fopen($path[$i], 'r');
Записывает содержимое в переменную
$text = fread($file, filesize($path[$i]));
Закрывает файл
fclose($file);
Затем считает сколько совпадений в содержимом файла
$result = substr_count($text, $naity[$i]);
и если кол-во совпадений соответствует требуемому кол-ву то делает замену и записывает результат в переменную.
$result_zamena = str_replace($naity[$i], $zamena[$i], $text);

Затем разумеется открывает файл для записи
$file = fopen($path[$i], 'w');
И записывает все обратно в файл.
fwrite($file, $result_zamena);
Закрывает файл
fclose($file);

ну разумеется там еще куча строк для вывода интерфейса мол ищем нашли, заменили все круто и бла бла бла.
и все вродебы ничего НО

Почему-то в половине файлов (как я заметил если файл большой, хотя может и ошибаюсь) после записи в конце обрезает несколько строк. Вот не могу понять почему оно их обрезает.
Может кто сталкивался с таким. Что я делаю неправильно?
Спасибо. )
  • 0

#5 badisoft

    Продвинутый пользователь

  • Assistent vsupport.club
  • PipPipPip
  • 5075 сообщений
Репутация: 786
Мастер

Отправлено 30 April 2012 - 09:22 PM

А до какого размера обрезается файл? В байтах.

Кстати (отвлеченно), а зачем fopen/fread/filesize/fclose в случае, когда файл целиком считывается в переменнную? file_get_contents, IMHO, сделает это ровно так же.

Кстати, цитата: "Использование функции file_get_contents() наиболее предпочтительно в случае необходимости получить содержимое файла целиком, поскольку для улучшения производительности функция использует алгоритм 'memory mapping' (если поддерживается операционной системой)."

Может, как раз этого memory_mapping и не хватает для больших файлов? Попробуй?

Да и с записью в файл я все время file_put_contents использую, так короче получается, а смысл тот же, если полностью файл переписать надо.
  • 1
http://cpu.badisoft.ru (тестовый сайт), http://badisoft.ru (модули)

#6 R.Sergey

    Администратор

  • Администраторы
  • 2810 сообщений
Репутация: 332
Мастер

Отправлено 01 May 2012 - 07:55 PM

Спасибо file_get_contents() действительно гораздо удобнее и все отлично работает.
А вот file_put_contents что-то не пишет в файл хоть убей....

И вот только когда начал писать этот дошло что я не выставил права на запись.
Выставил проверил - оляля все работает, но возник вопрос это мне для моих 200 файлов нужно менять права до установки а потом обратно после установки.
попробовал chmod - чтото не установило права, но даже допустим установит, придется делать несколько операций
считывать права, устанавливать 666 - затем запись в файл и снова менять на теже что считались......... т.е. по сути проще даже использовать

$file = fopen($path[$i], 'w');
fwrite($file, $result_zamena);
fclose($file);



Так и сделал и облом....... не записало нифига пока не поставил права на запись.

В недоумении вернулся к тому начальному варианту когда все записывалось (без ручной установки прав на запись) но обрезался файл в конце......... и что :huh: нифига не работает.

Не пойму толи лыжи не едут....... толи я .........

Скажите
$file = fopen($path[$i], 'w');

вот при записи в файл через эту конструкцию, нужно ли все-таки выставлять права на файл или ключ "w" таки откроет файл для записи........ а то я уже нихрена не пойму что у метя тут происходит. ((((
  • 0

#7 badisoft

    Продвинутый пользователь

  • Assistent vsupport.club
  • PipPipPip
  • 5075 сообщений
Репутация: 786
Мастер

Отправлено 01 May 2012 - 08:21 PM

вот при записи в файл через эту конструкцию, нужно ли все-таки выставлять права на файл или ключ "w" таки откроет файл для записи

Конечно, нужно. Рассуди "от обратного" - если бы кому-угодно можно было разрешить запись в файл путем задания ключика "w" у функции fopen, то какой вообще смысл во всех этих правах? :)

Ключик "w" работает немного по разному если файл уже есть или его нет. Если файл уже есть, то он открывается на запись и урезается до нулевой длины. Естественно, при этом важны права доступа к файлу. Если запись запрещена для пользователя (группы), из под которого выполняется php (Апач?), то вместо открытия файла будет false на выходе. Если файла нет, то он создается и при этом уже важны права на папку, которые вполне могут разрешать создание файла этому пользователю (группе) или не разрешать.
  • 0
http://cpu.badisoft.ru (тестовый сайт), http://badisoft.ru (модули)

#8 R.Sergey

    Администратор

  • Администраторы
  • 2810 сообщений
Репутация: 332
Мастер

Отправлено 01 May 2012 - 08:29 PM

Конечно, нужно. Рассуди "от обратного" - если бы кому-угодно можно было разрешить запись в файл путем задания ключика "w" у функции fopen, то какой вообще смысл во всех этих правах?


Да да я об этом тоже задумался......... но смутило то, что у меня все работало без выставления прав, иначе я бы не пришел к ошибке с обрезанием файлов.
Сейчас вот проверил раз 100 нифига без выставления прав не записывается......... и дошло. Зависит от настроек сервера видимо, т.к. предыдущий раз я тестировал все на хостинге клиента, прямо в процессе установки, после УДАЧНОЙ записи пришлось проверить все измененные файлы и в урезанных добавить недостающую часть.
А теперь тестирую на своем и это не работает. Т.е. получается у заказчиках - хостеры - ламеры.

Оки это хоть что-то объясняет, теперь буду разбираться с chmod - почему права не задает, может тоже из-за настроек сервера.
  • 0

#9 R.Sergey

    Администратор

  • Администраторы
  • 2810 сообщений
Репутация: 332
Мастер

Отправлено 02 May 2012 - 12:30 PM

Короче хрень какая-то мне уже поднадоело даже, но вопрос остается открытым.
Зачем нужна функция в php chmod () - если права нею изменить все равно невозможно.

Права не меняются как я понимаю т.к. другой владелец файла, т.е. если бы файл был создан пользователем apache то все бы работало (а может и нет).

Решил проверить и полез менять владельца. Через фтп это разумеется невозможно, через панель хостинга тоже, полез через ssh
И что!?!?!
это выдает

chown -R apache:apache test
chown: changing ownership of `test': Operation not permitted

это выдает

find test -type f -exec chown apache:apache  {} \;

Permission denied

Погуглил:
Как ни странно нашел якобы возможность изменения прав в обход владельца.
http://hoster01.ru/c...ok-i-failov#res
http://hoster01.ru/c...-papok-i-failov

Пофиг - ничего не помогает. ((((
  • 0

#10 badisoft

    Продвинутый пользователь

  • Assistent vsupport.club
  • PipPipPip
  • 5075 сообщений
Репутация: 786
Мастер

Отправлено 02 May 2012 - 01:56 PM

Решил проверить и полез менять владельца. Через фтп это разумеется невозможно

Почему? Я не знаю протокол и набор номанд для этого действия, но в FAR при FTP-доступе достаточно нажать Ctl-A (Set attributes) на файле и получишь девять стандартных полей (например, [x][x][ ] [x][ ][ ] [ ][ ][ ]) для смены прав доступа к файлу. Естественно, надо, чтобы доступ по FTP осуществлялся тем же юзером, кому принадлежит этот файл. Если файл принадлежит apache, а доступ идет под ftpuser, то права по FTP сменить не получится.

Как ни странно нашел якобы возможность изменения прав в обход владельца

Это не в обход, а совершенно нормальный разрешенный путь. Апач запущен с правами пользователя apache, файлы принадлежат пользователю apache и смена прав на эти файлы в данному случае совершенно валидна. А что при этом исполняемый скрипт, который меняет права принадлежит вовсе не пользователю apache, так мы ж сами этому скрипту выставляем права доступа "для всех".

ачем нужна функция в php chmod () - если права нею изменить все равно невозможно.

Подозреваю, что право выполнения этой функции (как и функции exec) настраивается. Думаю, что даже не в самом Апаче, а именно юзеру apache запрещается исполнение по exec и смена прав. Но это мои преположения, т.к. я у себя этого не делал. exec запрещают практически все провайдеры по понятной причине, слишком легок взлом при его разрешении. Думаю, c chmod аналогично.
  • 0
http://cpu.badisoft.ru (тестовый сайт), http://badisoft.ru (модули)

#11 R.Sergey

    Администратор

  • Администраторы
  • 2810 сообщений
Репутация: 332
Мастер

Отправлено 02 May 2012 - 03:24 PM

Почему? Я не знаю протокол и набор номанд для этого действия, но в FAR при FTP-доступе достаточно нажать Ctl-A (Set attributes) на файле и получишь девять стандартных полей (например, [x][x][ ] [x][ ][ ] [ ][ ][ ]) для смены прав доступа к файлу.


прочитай внимательно то что написал я )) я говорю не о правах на файл, а о смене владельца файла.

Это не в обход, а совершенно нормальный разрешенный путь. Апач запущен с правами пользователя apache, файлы принадлежат пользователю apache и смена прав на эти файлы в данному случае совершенно валидна. А что при этом исполняемый скрипт, который меняет права принадлежит вовсе не пользователю apache, так мы ж сами этому скрипту выставляем права доступа "для всех".


Вот этого не понял вовсе. Скрипт этот не работает, т.е. права не меняются.................. ((

Подозреваю, что право выполнения этой функции (как и функции exec) настраивается. Думаю, что даже не в самом Апаче, а именно юзеру apache запрещается исполнение по exec и смена прав. Но это мои преположения, т.к. я у себя этого не делал. exec запрещают практически все провайдеры по понятной причине, слишком легок взлом при его разрешении. Думаю, c chmod аналогично.

Ну да настраивается на сервере, но не буду же я перенастраивать сервер и жертвовать безопасностью чтобы заработала эта функция....... да и к тому же сервер то всегда разный. В итоге при правильно настроенном сервере функция бесполезна.

И как не крути права нужно будет ручками выставлять.....
  • 0

#12 badisoft

    Продвинутый пользователь

  • Assistent vsupport.club
  • PipPipPip
  • 5075 сообщений
Репутация: 786
Мастер

Отправлено 02 May 2012 - 04:26 PM

В итоге при правильно настроенном сервере функция бесполезна.

Ну да. Собственно, если сократить все написанное, то об этом и речь :).
Не очень, правда, понимаю, почему ты не можешь сменить владельца по ssh. Или это не рутовый ssh-доступ, а юзерский?

PS. Я тоже поначалу был удивлен, что некоторые функции типа exec, system и даже иногда rename нифига не работают. А оказалось, что так и надо.
  • 0
http://cpu.badisoft.ru (тестовый сайт), http://badisoft.ru (модули)

#13 R.Sergey

    Администратор

  • Администраторы
  • 2810 сообщений
Репутация: 332
Мастер

Отправлено 02 May 2012 - 04:31 PM

Не очень, правда, понимаю, почему ты не можешь сменить владельца по ssh. Или это не рутовый ssh-доступ, а юзерский?

Да вот и я не понимаю, вродебы рутовый но на определенный сайт. Хотя получается что нихрена он не рутовый если не дает сменить владельца. Да фиг с ним - мне надоело уже играться, пока к работе возвращаться......... а то пока я тут фигней страдаю, она накапливается.
  • 0

#14 R.Sergey

    Администратор

  • Администраторы
  • 2810 сообщений
Репутация: 332
Мастер

Отправлено 03 November 2012 - 06:49 PM

Привет.
Вопрос на засыпку ))
Как правильно сделать выборку по одному случайному товару из каждой категории, которые имеются, исключив при этом несколько категорий.
:)
  • 0

#15 badisoft

    Продвинутый пользователь

  • Assistent vsupport.club
  • PipPipPip
  • 5075 сообщений
Репутация: 786
Мастер

Отправлено 03 November 2012 - 08:10 PM

исключить просто - WHERE categoryID NOT IN (2,3,5,8,11)
сгруппировать - GROUP BY categoryID
Но это будет по одному ПЕРВОМУ товару от каждой категории кроме заданных.
А вот чтобы был еще и не первый, а случайный - мне в голову не приходит.
ИМХО, проще в несколько запросов, т.е. рандом делать на уровне PHP.
  • 0
http://cpu.badisoft.ru (тестовый сайт), http://badisoft.ru (модули)

#16 R.Sergey

    Администратор

  • Администраторы
  • 2810 сообщений
Репутация: 332
Мастер

Отправлено 03 November 2012 - 08:19 PM

Как правильно сделать выборку по одному случайному товару из каждой категории, которые имеются, исключив при этом несколько категорий.


В общем как сделал я, не знаю скорее всего есть более простое или правильное решение, но я пока что-то ничего лучше не придумал.
Или запросить массив с категориями, исключая ненужные, и затем запросом

SELECT t1.productID, t1.name, t1.Price, t2.filename FROM emph_products AS t1 JOIN emph_product_pictures AS t2 WHERE t1.enabled = '1' and t1.productID = t2.productID and Price > 0" and categoryID =    $categoryID   ORDER BY RAND() LIMIT 1;
подставлять по очереди айди категории.

или
чтобы не плодить кучу запросов.

записать все товары в массив
$sql = "SELECT t1.categoryID, t1.productID, t1.name, t1.Price, t2.filename FROM emph_products AS t1 JOIN emph_product_pictures AS t2 WHERE t1.enabled = '1' and t1.productID = t2.productID
  and categoryID != '1'
  and categoryID != '43'
  and Price > 0";

$result = mysql_query($sql, $conn);

разбить массив на массивы по категориям и туда же записать все что нужно о товаре
while ($row = mysql_fetch_assoc($result)){
  $cat[$row['categoryID']][] = $row['productID']."|".$row['name']."|".$row['Price']."|".$row['filename'];
}

ну и в конце концов сделать рандомный выбор товара из массива
foreach ($cat as $key => $value) {
  $rand_value = array_rand ($value);
  $val[] = explode("|",$cat[$key][$rand_value]);
}

в результате получаю массив $val с массивами, содержащими данные рандомно выбранных товаров.

ну и потом вывожу
$i = 0;
while ($i < count($val)){
  $ok .= "
    <div style='height: 213px; vertical-align: middle; display: table-cell;'>
	 <a href='/data/big/{$val[$i]['3']}' onclick='return hs.expand(this)'>
	  <img style='border: 2px solid #FF3C00; margin: 10px 0 0; padding: 2px;' width='160px' src=\"/data/medium/{$val[$i]['3']}\" alt=\"{$val[$i]['1']}\">
	 </a>
    </div>
    <a target='_blank' style='font-size: 14px; font-weight: bold;' href=\"/product_{$val[$i]['0']}.html\">
	 {$val[$i]['1']}
    </a>
    <div style='background: #FF3C00; color: #FFFFFF; font-size: 14px; font-weight: bold; padding: 5px 0; width: 180px;'>
	 Цена: {$val[$i]['2']} грн.
	 <a target='_blank' style='font-size: 13px; background: #fff; float: right; display: block; padding: 0px 10px; margin: 0px 5px;' href=\"/product_{$val[$i]['0']}.html\">
	  Купить
	 </a>
    </div>
  "; 
  $i++;
}
echo  $ok;


Можно упростить?
  • 0

#17 badisoft

    Продвинутый пользователь

  • Assistent vsupport.club
  • PipPipPip
  • 5075 сообщений
Репутация: 786
Мастер

Отправлено 03 November 2012 - 08:37 PM

Я бы делал так (1, 2 и 3 - категории, которые не должны участвовать):

$prod = array();
$data=db_query("SELECT COUNT(*) AS count, categoryID FROM xxxx_products WHERE categoryID NOT IN (1,2,3) GROUP BY categoryID");
while ($row = db_fetch_assoc($data))
$prod[] = db_fetch_assoc(db_query("SELECT * FROM xxxx_products WHERE categoryID=".$row['categoryID']." LIMIT ".rand(1, $row['count']).",1"));

Где-то наверняка будут ошибки, но общая идея понятна - получаем список количества товаров для всех участвующих категорий, затем из каждой делаем случайную выборку. Запросок не много и они, как я понимаю, нересурсоемки.
  • 0
http://cpu.badisoft.ru (тестовый сайт), http://badisoft.ru (модули)

#18 R.Sergey

    Администратор

  • Администраторы
  • 2810 сообщений
Репутация: 332
Мастер

Отправлено 03 November 2012 - 08:43 PM

я не понял а зачем запрашивать категории из таблицы xxxx_products и групировать, а не запросить их из таблицы с категориями?

И все равно как я понял у тебя получается куча запросов, а точнее столько же сколько и категорий, если у меня 26 категорий, то это + 26 запросов к БД.

И вот вопрос, вариант с запросами делает нагрузку на БД, а вариант с массивами делает нагрузку на сервер... что лучше )))) а точнее что оптимальней!?!?!
  • 0

#19 badisoft

    Продвинутый пользователь

  • Assistent vsupport.club
  • PipPipPip
  • 5075 сообщений
Репутация: 786
Мастер

Отправлено 03 November 2012 - 08:53 PM

я не понял а зачем запрашивать категории из таблицы xxxx_products и групировать, а не запросить их из таблицы с категориями?

Ну откуда же в таблице с категориями информация о количестве товаров в каждой? :)
COUNT(*) дает количество строк в запросе. При групировке - в каждой группе. При группировке по категории - в категории.

И все равно как я понял у тебя получается куча запросов, а точнее столько же сколько и категорий, если у меня 26 категорий, то это + 26 запросов к БД.

Ну да. Как мне думается, это минимум, если делать запросами. Хотя, конечно, можно сделать вообще хранимую процедуру на сервере и получать готовый результат, типа такого - http://habrahabr.ru/post/54176/ . Ну а что лучше, много простых запросов и простая обработка на PHP или один запрос и более сложная его обработка (табличка-то полученная со ВСЕМИ товарами памяти откушает весьма немало) - черт его знает. Особенно если PHP выполняется на одном ресурсе, а sql-сервер находится на другом. Видимо, надо чем-то проверять скорость и нагрузку при обоих решениях в конкретном случае, но я даже инструментария для такой проверки не знаю.
  • 0
http://cpu.badisoft.ru (тестовый сайт), http://badisoft.ru (модули)

#20 R.Sergey

    Администратор

  • Администраторы
  • 2810 сообщений
Репутация: 332
Мастер

Отправлено 03 November 2012 - 08:56 PM

Ну откуда же в таблице с категориями информация о количестве товаров в каждой?

ну как откуда из поля products_count
  • 0