32 заметки с тегом

php РСС

31 мая 2011, 19:07

PHP: array_key_exists for multidimensional arrays

function array_key_exists_r($needle, $haystack)
{
    $result = array_key_exists($needle, $haystack);
    if ($result) return $result;
    foreach ($haystack as $v) {
        if (is_array($v)) {
            $result = array_key_exists_r($needle, $v);
        }
        if ($result) return $result;
    }
    return $result;
}
php

27 мая 2011, 18:38

PHP: MySQL get FOREIGN KEY

$result = mysql_query("SHOW CREATE TABLE $table_name");
while ($rowI = mysql_fetch_assoc($result, MYSQL_NUM)) {
	if(preg_match_all(
 		'/FOREIGN KEY \(`(.*)`\) REFERENCES `(.*)` \(`(.*)`\)/',
 		$rowI[1],
 		$matchArr)) {
			printr($matchArr);
	}
}	
mysql   php

29 апреля 2011, 14:58

PHP: detect UTF8 :D

function detectUTF8($string)
{
    return preg_match('%(?:
        [\xC2-\xDF][\x80-\xBF]             # non-overlong 2-byte
        |\xE0[\xA0-\xBF][\x80-\xBF]        # excluding overlongs
        |[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
        |\xED[\x80-\x9F][\x80-\xBF]        # excluding surrogates
        |\xF0[\x90-\xBF][\x80-\xBF]{2}     # planes 1-3
        |[\xF1-\xF3][\x80-\xBF]{3}         # planes 4-15
        |\xF4[\x80-\x8F][\x80-\xBF]{2}     # plane 16
        )+%xs', 
    $string);

}
php   utf8

14 апреля 2011, 8:33

Новый PHP новые правила :) Лечим быстро растущий еррор_лог

На одном проекте, написанном н-лет назад обновили апачь+пхп+мускул+нгинксс, и скорость толстения логов просто поражала. Например за сутки лог апача из-за ошибок пхп выростал до 2ух гиг :)

За 1 заход простого юзера плюс 1-20МБ, это конечно замечательно, но нужно было как-то «пофиксить». Самым толстым ворнингом был такой:
Warning: strtotime()/strftime()/date() [function.strftime]: It is not safe to rely on the 
system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() 
function. In case you used any of those methods and you are still getting this warning, you most likely 
misspelled the timezone identifier.

Пхп, просто хотел знать дефаулт тайм-зоун, и ругался на все функции которые работают с датой :) В начале «главного» скрипта пишем:
date_default_timezone_set('UTC');


Следующий ворнинг:
PHP Deprecated:  Function ereg()/eregi()/ereg_replace() is deprecated in *

Это значит что, эти функции ereg()/eregi()/ereg_replace() нихт_арбайтен, то есть не работают, вообще. Да, в новом пхп их убили, почитать что убили можно здесь

«-Что же делать?», воскликнет читатель. Есть два пути.
  • заменить все дохлые функции живыми аналогами
    // Все меняем на preg_match
    ereg("\.([^\.]*$)", $this->file_src_name, $extension);
    preg_match("/\.([^\.]*$)/", $this->file_src_name, $extension);
    // да, на preg_match
    $this->file_dst_name_body = ereg_replace("[^A-Za-z0-9_]", "", $this->file_dst_name_body);
    $this->file_dst_name_body = preg_replace("/[^A-Za-z0-9_]/", "", $this->file_dst_name_body);
    // тут появится модификатор regexpа
    eregi("\.([^\.]*$)", $this->file_src_name, $extension);
    preg_match("/\.([^\.]*$)/i", $this->file_src_name, $extension);
  • в настройках включить поддержку старых функций, которая отрубает поддержку новых
    mbstring.func_overload = 7
Если код старый и ТОЛСТы, можно обойтись и заменой в хтакцесс, а если нет, то лучше да ;)
bugs   php

1 апреля 2011, 19:42

PHP: отладка в сложнодоступных местах :)

ob_start();

	print_r(get_defined_vars());
	
$output = ob_get_contents(); 
ob_end_clean();

$f = fopen('output.txt', 'w+');

fwrite($f, $output);
fclose($f);
debug   php

24 марта 2011, 12:45

PHP: strtolower, strtoupper и кириллица

Эти функции на кириллицу просто так не обращают внимания. Строки остаются без изменений, печаль и т. д. В данном случае могут помочь mb_* мультибайтовые аналогичные функции, но если их нет, нужно просто правильно поставить локаль, и простая функция заработает как нужно.
setlocale(LC_ALL, 'ru_RU');
$name = strtolower($name);
php

20 марта 2011, 23:35

PHP: sort multiple array (ASC, DESC)

function array_orderby(){
    $args = func_get_args();
    $data = array_shift($args);
    foreach ($args as $n => $field) {
        if (is_string($field)) {
            $tmp = array();
            foreach ($data as $key => $row)
                $tmp[$key] = $row[$field];
            $args[$n] = $tmp;
            }
    }
    $args[] = &$data;
    call_user_func_array('array_multisort', $args);
    return array_pop($args);
}
$results = array_orderby ($results, "P", SORT_DESC, "GD", SORT_DESC);

В похапе 5.3 мы получим болт а не сортировку, потому пришлось искать замену, и первое что приглянулось, это вот такой код с анонимными функциями и усорт
function sort_multi_array ($array, $key){
  $keys = array();
  for ($i=1;$i<func_num_args();$i++) {
    $keys[$i-1] = func_get_arg($i);
  }
  // create a custom search function to pass to usort

  $func = function ($a, $b) use ($keys) {
    for ($i=0;$i<count($keys);$i++) {
      if ($a[$keys[$i]] != $b[$keys[$i]]) {
        return ($a[$keys[$i]] < $b[$keys[$i]]) ? -1 : 1;
      }
    }
    return 0;
  };
  usort($array, $func);
  return $array;
} 

Здесь мы получим сортировку АСК по всем ключам, что бы сделать обратную используем аррай_реверс, а что бы ключи работали в функции — нужно подумать, может когда будет нужно переделаю, на данном этапе мне достаточно этого.

чиирз
php

17 марта 2011, 10:46

PHP: превращаем слово единственного числа в множественное

Нужно было, быстро на коленке стряпать такую вот функцию. Изначально она была сделана по примерам возможных слов, и приняла такой вид:
function make_multiple($word) {
	$word = trim($word);
	$lst1 = substr($word,-1);$rest1 = substr($word,0,-1);
	$lst2 = substr($word,-2);$rest2 = substr($word,0,-2);
	$lst3 = substr($word,-3);$rest3 = substr($word,0,-3);
	
	if ($lst3 == "нки") $word = $rest3."нков";
	elseif ($lst2 == "ки" || $lst2 == "ка") $word = $rest2."ок";
	elseif ($lst2 == "ры") $word = $rest2."р";
	elseif ($lst2 == "ия") $word = $rest2."ий";
	elseif ($lst2 == "рь") $word = $rest2."рей";
	elseif ($lst1 == "ы") $word = $rest1."ов";
	
	return $word;
}

Взглянув на это, стало как-то печально, особенно если учитывать что примеров может быть намного больше, взял и автоматизировал/оптимизировал:
function make_multiple($word) {
	$word = trim($word);
	//  массив возможных вариантов
	$ends = array(
		"нки" => "нков",
		"ки" => "ок",
		"ка" => "ок",
		"ры" => "р",
		"ия" => "ий",
		"рь" => "рей",
		"ы" => "ов"
	);
	// ищем самое большое окончание, то есть его длину
	$itrs = max(array_map('strlen', array_keys($ends)));
	$poly = array();
	// строим массив этих окончаний, и слов без них
	for ($i = $itrs; $i > 0 ; $i--) {
		// в таком виде что бы избежать циклов в цикле
		$poly[$i] = array(substr($word,-$i),substr($word,0,-$i));
	}
	// строим нужно слово, когда найдём сопадение
	foreach ($ends as $what => $to) {
		if ($poly[strlen($what)][0] == $what) {
			return $poly[strlen($what)][1].$to;
		}
	}	
	return $word;
}

Вот так родился такой монстрик ;) А сами окончания наверное правильнее будет передавать в функцию, хотя если они останутся в ней, база нарастёт быстрее.
optimizing   php

3 марта 2011, 16:36

Универсальный print_r

Окончательный ремейк будет выглядеть вот-так:
if (!function_exists('printr')) {
	function printr($array) {
		$args = func_get_args();
		if (count($args) > 1) {
			foreach ($args as $values)
				printr($values);
		} else {
			if (is_array($array) || is_object($array)) {
				echo "<pre>";
				print_r($array);
				echo "</pre>";
			} else echo $array;
		}
	}
}
printr($arr1,$arr2);
php

28 февраля 2011, 17:01

UFT8 и PHP

Казалось бы, как только начинаешь использовать мультибайт, тебя спасут теже функции, только с mb_ в начале, оказалось показалось %).
В них желательно не забывать указывать какую именно кодировку вы используете
mb_substr($var,0,99,'utf-8')
Что-то типа такого, и да, мануалы в помощь.

Для почитать на досуге, советую:



PS: нашёл у Тормоза в блоге. И к нему встречный вопрос, почему урл-заглушка в ДАОС не туда ведёт? :)
php   utf8

27 января 2011, 16:22

Обновления скриптов

mysql   php

26 января 2011, 19:02

PHP&MYSQL:Сравнение нескольких таблиц в БД и генерация скрипта обновления

Полгодика назад я написал артикль на тему сравнение таблиц в двух БД (и больше), основная идея которого была в том, что бы быстро сравнить 2 таблицы одинаковой системы с разными версиями и обновить старую БД. Делал всё руками, так как изменений было не много.

А тут настал час, когда нужно проделать тоже, но руками это будет адски долго. Уделив 2 часа на курение мускул-синтаксиса, я на коленке написал, так сказать, версию 2.0 :)

Полная генерация «апдейт ескуель»:
  • альтер чендж
  • альтер адд
  • криейт тейбл
  • адд индексес
  • ремув индексес
  • сам УИ импрувементс


mysql   php

25 января 2011, 11:35

PHP: get google.PR end yandex.QI (тИЦ)

Обновил скрипт, что и как смотреть в старой статье.


php

7 декабря 2010, 13:26

PHP: finish end tags in piece of HTML (close HTML tags)

Иногда нужно вывести кусок html, не весь, и что бы не сломать дизайн, многие «разработчики» (помню даже в яндексе такое видел), вставляют такой код:
</p></li></ul></td></tr></th></table></div>

Как говорится — это пиздец, потому рекомендую велосипед ниже, так как времени изобретать свой не нашлось :)
/**
 * close all open xhtml tags at the end of the string
 *
 * @param string $html
 * @return string
 * @author Milian Wolff <mail@milianw.de>
 */
 
function closetags($html) {
	#put all opened tags into an array
	preg_match_all('#<([a-z]+)(?: .*)?(?<![/|/ ])>#iU', $html, $result);
	$openedtags = $result[1];
	
	#put all closed tags into an array
	preg_match_all('#</([a-z]+)>#iU', $html, $result);
	$closedtags = $result[1];
	$len_opened = count($openedtags);
	
	# all tags are closed
	if (count($closedtags) == $len_opened) {
		return $html;
	}
	$openedtags = array_reverse($openedtags);
	
	# close tags
	for ($i=0; $i < $len_opened; $i++) {
		if (!in_array($openedtags[$i], $closedtags)){
			$html .= '</'.$openedtags[$i].'>';
		} else {
			unset($closedtags[array_search($openedtags[$i], $closedtags)]);
		}
	}
	return $html;
}
php

20 июня 2010, 16:57

Лучший xml2array

Немного наобламывавшись с предыдущим парсером, решил поискать что-то получше. Просмотрев с 50 парсеров, которые тупо не могли справится с моим примером xml, я таки нашёл тот, который это сделал очень быстро и без проблем.
function xml2array(&$string) {
    $parser = xml_parser_create();
    xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
    xml_parse_into_struct($parser, $string, $vals, $index);
    xml_parser_free($parser);
    $mnary=array();
    $ary=&$mnary;
    foreach ($vals as $r) {
        $t=$r['tag'];
        if ($r['type']=='open') {
            if (isset($ary[$t])) {
                if (isset($ary[$t][0])) $ary[$t][]=array(); else $ary[$t]=array($ary[$t], array());
                $cv=&$ary[$t][count($ary[$t])-1];
            } else $cv=&$ary[$t];
            if (isset($r['attributes'])) {foreach ($r['attributes'] as $k=>$v) $cv['_a'][$k]=$v;}
            $cv['_c']=array();
            $cv['_c']['_p']=&$ary;
            $ary=&$cv['_c'];
        } elseif ($r['type']=='complete') {
            if (isset($ary[$t])) { // same as open
                if (isset($ary[$t][0])) $ary[$t][]=array(); else $ary[$t]=array($ary[$t], array());
                $cv=&$ary[$t][count($ary[$t])-1];
            } else $cv=&$ary[$t];
            if (isset($r['attributes'])) {foreach ($r['attributes'] as $k=>$v) $cv['_a'][$k]=$v;}
            
            if (isset($r['value'])) $cv['_v'] = $r['value'];
        } elseif ($r['type']=='close') {
            $ary=&$ary['_p'];
        }
    }    
    
    _del_p($mnary);
    return $mnary;
}
function _del_p(&$ary) {
    foreach ($ary as $k=>$v) {
        if ($k==='_p') unset($ary[$k]);
        elseif (is_array($ary[$k])) _del_p($ary[$k]);
    }
}

Последняя функция удаляет результаты рекурсий ;)



php

9 июня 2010, 10:18

Сравнение таблиц в двух БД (и больше) Избранное

Когда дохера работы, начинаешь страдать такой ерундой :)
Раз в несколько месяцев приходится сравнивать БД, и каждый раз в ручную. Один даже раз софт сутки искал, но он ужасен, весь. Немного пострадав, минут 30, получился такой код:
  • собираем всё в масcив;
  • выводим всё красиво в табличках;
  • подключаем jQ и делаем удобную «обёрточку»;
  • ...
  • Profit
<?php
  $user  = "root";
  $userp = "";
  mysql_connect("localhost", $user, $userp) or die(mysql_error());
	$table2compare = array("test1", "test2");
	$comparedtables = array(); $i = 0;
  foreach ($table2compare as $tablename){
  	$comparedtables["title"][$i] = $tablename;
    $db = mysql_query("SHOW TABLES IN $tablename");
    while($dbt = mysql_fetch_array( $db )){
      $table = mysql_query("SHOW COLUMNS FROM $dbt[0] FROM $tablename ");
      while($tbf = mysql_fetch_array( $table ))
      	$comparedtables["tables"][$dbt[0]][$i][] = $tbf;
    }
    $i++;
  }
	echo "<table><tr>";
	for ($j = 0; $j < $i; $j++) 
		echo "<td>".$comparedtables["title"][$j]."</td>";
	echo "</tr>";
	foreach ($comparedtables["tables"] as $table => $fields) {
		echo "<tr>";
		for ($j = 0; $j < $i; $j++) {
			if ($j > 0) $eq = $fields[$j] == $fields[0]; else $eq = true;
			echo "<td valign='top' ".(!$eq ? "style='background: #fcc;'" : "").">";
			if (empty($fields[$j])) continue;
			echo "<span>$table</span><br><table rules=all frame=box cellpadding='2'>
            <tr>
            	<td>Field</td>
            	<td>Type</td>
            	<td>Null</td>
            	<td>Key</td>
            	<td>Default</td>
            	<td>Extra</td>
            </tr>";
  		foreach ($fields[$j] as $field)
	      echo "<tr>
	      				<td>$field[0]</td>
	      				<td>$field[1]</td>
	      				<td>$field[2]</td>
	        			<td>$field[3]</td>
	        			<td>$field[4]</td>
	        			<td>$field[5]</td>
	        		</tr>";
      echo "</table></td>";
    }
    echo "</tr>";
  }
  
  echo "</table>";
  mysql_close();
?>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.4.2.min.js"></script>
<script type="text/javascript">
	$(function(){
	  $("table table").hide();
	  $("table span").click(function(){
	  	$(this).next().next().toggle();
	  }).css({"cursor":"pointer"});
	});
</script>
javascript   mysql   php

12 апреля 2010, 11:04

PHP: Тырим погоду и пробки с яндекса :)

Сам яндекс жадная сволочь, прямой ссылки не даёт на состояние пробок. Зато у него есть выджет для вин7, в котором я нашёл ссылку на нужный мне xml.
http://export.yandex.ru/bar/reginfo.xml

Дальше что нам нужно? :)
  1. открываем наш файл
  2. конвертируем в нашу любимую кодировку
  3. xml бахаем в масив
  4. ...
  5. Профит
ps: местоположение определяется автоматически, по айпи, что бы выбрать другой город, нужно пользоваться анонимными проксями, скорее всего ;)

pps: немного покопавшись, секунд 5 :D нарыл всё нужное.
Для определения региона нужна переменная ncrnd
http://export.yandex.ru/bar/reginfo.xml?ncrnd=8412

Что бы получить код региона, у шмяндекса есть форма
http://tune.yandex.ru/region/





php

14 марта 2010, 23:53

PHP: выводим первые 3 предложения (можно любые 3)

echo implode(".",array_slice(explode (".", $bigtext), 0, 3))
  • Делим текст через точки на массив
  • Отрезаем первые 3 элемента массива
  • Делаем из массива обратно текст используя точку %)
php

24 февраля 2010, 10:25

php: первый и последний в массиве %)

// значения
$first = reset($array);
$last = end($array);
// ключи
$first = reset(array_keys($array));
$last = end(array_keys($array));
php

21 декабря 2009, 15:49

PHP: in_string (аналог in_array)

function in_string($needle, $haystack, $insensitive = 0) {
	if ($insensitive) {
		return (false !== stristr($haystack, $needle)) ? true : false;
	} else {
		return (false !== strpos($haystack, $needle)) ? true : false;
	}
}	
Как видим, это просто stristr и strpos ;)
Ctrl +  Ранее