Буквенные сокращения стран

<?php
/**
 * Буквенные сокращения стран
 * автор: Nc_Soft
 * 27.03.09
 */

$country=array(
'AC' => 'Ascension Island (остров Вознесения)', 
'AD' => 'Andorra (Андорра)', 
'AE' => 'United Arab Emirates (Объединенные Арабские Эмираты)', 
'AF' => 'Afghanistan (Афганистан)', 
'AG' => 'Antigua and Barbuda (Антигуа и Барбуда)', 
'AI' => 'Anguilla', 
'AL' => 'Albania (Албания)', 
'AM' => 'Armenia (Армения)', 
'AN' => 'Netherlands Antilles (Голланские Антильские острова)', 
'AO' => 'Angola (Ангола)', 
'AQ' => 'Antarctica (Антарктика)', 
'AR' => 'Argentina (Аргентина)', 
'AS' => 'American Samoa (Американское Самоа)', 
'AT' => 'Austria (Австрия)', 
'AU' => 'Australia (Австралия)', 
'AW' => 'Aruba (Аруба)', 
'AX' => 'Aland Islands (Аландские острова)', 
'AZ' => 'Azerbaijan (Азербайджан)', 
'BA' => 'Bosnia and Herzegovina (Босния и Герцеговина)', 
'BB' => 'Barbados (Барбадос)', 
'BD' => 'Bangladesh (Бангладеш)', 
'BE' => 'Belgium (Бельгия)', 
'BF' => 'Burkina Faso (Буркина-Фасо)', 
'BG' => 'Bulgaria (Болгария)', 
'BH' => 'Bahrain (Бахрейн)', 
'BI' => 'Burundi (Бурунди)', 
'BJ' => 'Benin (Бенин)', 
'BM' => 'Bermuda (Бермудские острова)', 
'BN' => 'Brunei Darussalam (Бруней)', 
'BO' => 'Bolivia (Боливия)', 
'BR' => 'Brazil (Бразилия)', 
'BS' => 'Bahamas (Багамские острова)', 
'BT' => 'Bhutan (Бутан)', 
'BV' => 'Bouvet Island', 
'BW' => 'Botswana (Ботсвана)', 
'BY' => 'Belarus (Беларусь)', 
'BZ' => 'Belize (Белиз)', 
'CA' => 'Canada (Канада)', 
'CC' => 'Cocos (Keeling) Islands (Кокосовые острова)', 
'CD' => 'Congo (Конго)', 
'CF' => 'Central African Republic (Центральноафриканская Республика)', 
'CG' => 'Congo (Конго)', 
'CH' => 'Switzerland (Швейцария)', 
'CI' => 'Cote dIvoire (Кот-дИвуар)', 
'CK' => 'Cook Islands (острова Кука)', 
'CL' => 'Chile (Чили)', 
'CM' => 'Cameroon (Камерун)', 
'CN' => 'China (Китай)', 
'CO' => 'Colombia (Колумбия)', 
'CR' => 'Costa Rica (Коста-Рика)', 
'CS' => 'Serbia and Montenegro (Сербия и Черногория)', 
'CU' => 'Cuba (Куба)', 
'CV' => 'Cape Verde (Кабо-Верде)', 
'CX' => 'Christmas Island (остров Рождества)', 
'CY' => 'Cyprus (Кипр)', 
'CZ' => 'Czech Republic (Чехия)', 
'DE' => 'Germany (Германия)', 
'DJ' => 'Djibouti (Джибути)', 
'DK' => 'Denmark (Дания)', 
'DM' => 'Dominica (Доминика)', 
'DO' => 'Dominican Republic (Доминиканская Республика)', 
'DZ' => 'Algeria (Алжир)', 
'EC' => 'Ecuador (Эквадор)', 
'EE' => 'Estonia (Эстония)', 
'EG' => 'Egypt (Египет)', 
'EH' => 'Western Sahara (Западная Сахара)', 
'ER' => 'Eritrea (Эритрея)', 
'ES' => 'Spain (Испания)', 
'ET' => 'Ethiopia (Эфиопия)', 
'FI' => 'Finland (Финляндия)', 
'FJ' => 'Fiji (Фиджи)', 
'FK' => 'Falkland Islands (Фолклендские острова)', 
'FM' => 'Micronesia (Микронезия)', 
'FO' => 'Faroe Islands (Фарерские острова)', 
'FR' => 'France (Франция)', 
'GA' => 'Gabon (Габон)', 
'GB' => 'United Kingdom (Соединенное Королевство Великобритании и Северной Ирландии)', 
'GD' => 'Grenada (Гренада)', 
'GE' => 'Georgia (Грузия)', 
'GF' => 'French Guiana (Французская Гвиана)', 
'GG' => 'Guernsey (остров Гернси)', 
'GH' => 'Ghana (Гана)', 
'GI' => 'Gibraltar (Гибралтар)', 
'GL' => 'Greenland (Гренландия)', 
'GM' => 'Gambia (Гамбия)', 
'GN' => 'Guinea (Гвинея)', 
'GP' => 'Guadeloupe (Гваделупа)', 
'GQ' => 'Equatorial Guinea (Экваториальная Гвинея)', 
'GR' => 'Greece (Греция)', 
'GS' => 'South Georgia and the South Sandwich Islands (Южная Джорджия и Южные Сандвичевы острова)', 
'GT' => 'Guatemala (Гватемала)', 
'GU' => 'Guam (Гуам)', 
'GW' => 'Guinea-Bissau (Гвинея-Бисау)', 
'GY' => 'Guyana (Гайана)', 
'HK' => 'Hong Kong (Гонконг)', 
'HM' => 'Heard and McDonald Islands', 
'HN' => 'Honduras (Гондурас)', 
'HR' => 'Croatia/Hrvatska (Хорватия)', 
'HT' => 'Haiti (Гаити)', 
'HU' => 'Hungary (Венгрия)', 
'ID' => 'Indonesia (Индонезия)', 
'IE' => 'Ireland (Ирландия)', 
'IL' => 'Israel (Израиль)', 
'IM' => 'Isle of Man (остров Мэн)', 
'IN' => 'India (Индия)', 
'IO' => 'British Indian Ocean Territory', 
'IQ' => 'Iraq (Ирак)', 
'IR' => 'Iran (Иран)', 
'IS' => 'Iceland (Исландия)', 
'IT' => 'Italy (Италия)', 
'JE' => 'Jersey (остров Джерси)', 
'JM' => 'Jamaica (Ямайка)', 
'JO' => 'Jordan (Иордания)', 
'JP' => 'Japan (Япония)', 
'KE' => 'Kenya (Кения)', 
'KG' => 'Kyrgyzstan (Кыргызстан)', 
'KH' => 'Cambodia (Камбоджа)', 
'KI' => 'Kiribati (Кирибати)', 
'KM' => 'Comoros (Коморские острова)', 
'KN' => 'Saint Kitts and Nevis (Сент-Китс и Невис)', 
'KP' => 'Korea (Северная Корея)', 
'KR' => 'Korea (Южная Корея)', 
'KW' => 'Kuwait (Кувейт)', 
'KY' => 'Cayman Islands (Каймановы острова)', 
'KZ' => 'Kazakhstan (Казахстан)', 
'LA' => 'Lao (Лаос)', 
'LB' => 'Lebanon (Ливан)', 
'LC' => 'Saint Lucia (Сент-Люсия)', 
'LI' => 'Liechtenstein (Лихтенштейн)', 
'LK' => 'Sri Lanka (Шри-Ланка)', 
'LR' => 'Liberia (Либерия)', 
'LS' => 'Lesotho (Лесото)', 
'LT' => 'Lithuania (Литва)', 
'LU' => 'Luxembourg (Люксембург)', 
'LV' => 'Latvia (Латвия)', 
'LY' => 'Libya (Ливия)', 
'MA' => 'Morocco (Марокко)', 
'MC' => 'Monaco (Монако)', 
'ME' => 'Montenegro (Монтенегро)',
'MD' => 'Moldova (Молдова)', 
'MG' => 'Madagascar (Мадагаскар)', 
'MH' => 'Marshall Islands (Маршалловы острова)', 
'MK' => 'Macedonia (Македония)', 
'ML' => 'Mali (Мали)', 
'MM' => 'Myanmar (Мьянма)', 
'MN' => 'Mongolia (Монголия)', 
'MO' => 'Macau (Макао)', 
'MP' => 'Northern Mariana Islands (Северные Марианские острова)', 
'MQ' => 'Martinique (Мартиника)', 
'MR' => 'Mauritania (Мавритания)', 
'MS' => 'Montserrat (Монтсеррат)', 
'MT' => 'Malta (Мальта)', 
'MU' => 'Mauritius (Маврикий)', 
'MV' => 'Maldives (Мальдивы)', 
'MW' => 'Malawi (Малави)', 
'MX' => 'Mexico (Мексика)', 
'MY' => 'Malaysia (Малайзия)', 
'MZ' => 'Mozambique (Мозамбик)', 
'NA' => 'Namibia (Намибия)', 
'NC' => 'New Caledonia (Новая Каледония)', 
'NE' => 'Niger (Нигер)', 
'NF' => 'Norfolk Island (Норфолк)', 
'NG' => 'Nigeria (Нигерия)', 
'NI' => 'Nicaragua (Никарагуа)', 
'NL' => 'Netherlands (Нидерланды)', 
'NO' => 'Norway (Норвегия)', 
'NP' => 'Nepal (Непал)', 
'NR' => 'Nauru (Науру)', 
'NU' => 'Niue', 
'NZ' => 'New Zealand (Новая Зеландия)', 
'OM' => 'Oman (Оман)', 
'PA' => 'Panama (Панама)', 
'PE' => 'Peru (Перу)', 
'PF' => 'French Polynesia (Французская Полинезия)', 
'PG' => 'Papua New Guinea (Папуа - Новая Гвинея)', 
'PH' => 'Philippines (Филиппины)', 
'PK' => 'Pakistan (Пакистан)', 
'PL' => 'Poland (Польша)', 
'PM' => 'Saint Pierre and Miquelon (Сен-Пьер и Микелон)', 
'PN' => 'Pitcairn Island (остров Питкэрн)', 
'PR' => 'Puerto Rico (Пуэрто-Рико)', 
'PS' => 'Palestine (Палестина)', 
'PT' => 'Portugal (Португалия)', 
'PW' => 'Palau (Палау)', 
'PY' => 'Paraguay (Парагвай)', 
'QA' => 'Qatar (Катар)', 
'RE' => 'Reunion Island (остров Реюньон)', 
'RO' => 'Romania (Румыния)', 
'RU' => 'Russian Federation (Россия)', 
'RW' => 'Rwanda (Руанда)', 
'SA' => 'Saudi Arabia (Саудовская Аравия)', 
'SB' => 'Solomon Islands (Соломоновы Острова)', 
'SC' => 'Seychelles (Сейшельские Острова)', 
'SD' => 'Sudan (Судан)', 
'SE' => 'Sweden (Швеция)', 
'SG' => 'Singapore (Сингапур)', 
'SH' => 'Saint Helena (остров Святой Елены)', 
'SI' => 'Slovenia (Словения)', 
'SJ' => 'Svalbard and Jan Mayen Islands', 
'SK' => 'Slovakia (Словакия)', 
'SL' => 'Sierra Leone (Сьерра-Леоне)', 
'SM' => 'San Marino (Сан-Марино)', 
'SN' => 'Senegal (Сенегал)', 
'SO' => 'Somalia (Сомали)', 
'SR' => 'Suriname (Суринам)', 
'ST' => 'Sao Tome and Principe (Сан-Томе и Принсипи)', 
'SU' => 'exUSSR (СССР)', 
'SV' => 'El Salvador (Сальвадор)', 
'SY' => 'Syria (Сирия)', 
'SZ' => 'Swaziland (Свазиленд)', 
'TC' => 'Turks and Caicos Islands', 
'TD' => 'Chad (Чад)', 
'TF' => 'French Southern Territories', 
'TG' => 'Togo (Того)', 
'TH' => 'Thailand (Таиланд)', 
'TJ' => 'Tajikistan (Таджикистан)', 
'TK' => 'Tokelau (Токелау)', 
'TL' => 'Timor-Leste', 
'TM' => 'Turkmenistan (Туркменистан)', 
'TN' => 'Tunisia (Тунис)', 
'TO' => 'Tonga (Тонга)', 
'TP' => 'East Timor (Восточный Тимор)', 
'TR' => 'Turkey (Турция)', 
'TT' => 'Trinidad and Tobago (Тринидад и Тобаго)', 
'TV' => 'Tuvalu (Тувалу)', 
'TW' => 'Taiwan (Тайвань)', 
'TZ' => 'Tanzania (Танзания)', 
'UA' => 'Ukraine (Украина)', 
'UG' => 'Uganda (Уганда)', 
'UK' => 'United Kingdom (Соединенное Королевство Великобритании и Северной Ирландии)', 
'UM' => 'United States Minor Outlying Islands', 
'US' => 'United States (США)', 
'UY' => 'Uruguay (Уругвай)', 
'UZ' => 'Uzbekistan (Узбекистан)', 
'VA' => 'Holy See, Vatican (Ватикан)', 
'VC' => 'Saint Vincent and the Grenadines (Сент-Винсент и Гренадины)', 
'VE' => 'Venezuela (Венесуэла)', 
'VG' => 'Virgin Islands, British (Виргинские острова, Британские)', 
'VI' => 'Virgin Islands, US (Виргинские острова, США)', 
'VN' => 'Vietnam (Вьетнам)', 
'VU' => 'Vanuatu (Вануату)', 
'WF' => 'Wallis and Futuna Islands', 
'WS' => 'Western Samoa (Западное Самоа)', 
'YE' => 'Yemen (Йемен)', 
'YT' => 'Mayotte', 
'YU' => 'Yugoslavia (Югославия)', 
'ZA' => 'South Africa (ЮАР)', 
'ZM' => 'Zambia (Замбия)', 
'ZW' => 'Zimbabwe (Зимбабве)'
);

/*Сам этот массив уже интересен и ценен, но в
качестве примера выведем русское название для страны RU*/
$strana=$country['RU'];
echo substr( strtok($strana, ')'), strpos($strana, '(') + 1);

?>
28 марта 2009, 14:56

Получение информации о Российском ip адресе

<?php
/**
 * Получение информации о Российском ip адресе
 * автор: Nc_Soft
 * 26.03.09
 */

/*
http://ipgeobase.ru наконец-то сделали xml сервис для определения параметров сетей.
Теперь узнать из каких городов ваши посетители стало еще проще!
Описание сервиса на http://blog.ipgeobase.ru/?p=37
Там обещано выложить примеры для разных языков программирования, но пока что
не выложено вообще никаких примеров, поэтому я и создал этот snippet
Нам понадобятся curl и simplexml
*/

//ип который тестим
$ip='81.18.122.149';

$data=<<<XML
<ipquery>
	<fields>
		<all/>
	</fields>
	<ip-list>
		<ip>$ip</ip>
	</ip-list>
</ipquery>
XML
;

$ch=curl_init('http://194.85.91.253:8090/geo/geo.html');
curl_setopt($ch,CURLOPT_POST,1);
curl_setopt($ch,CURLOPT_POSTFIELDS,$data);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
$s=curl_exec($ch);
curl_close($ch);

//смотрим что отдал сервис
echo "<pre>\n";
echo htmlspecialchars($s);

//парсим ответ (можно регулярками, но зачем?)
$s=simplexml_load_string($s);

//выводим данные

echo 'диаппазон ';
echo $s->ip->inetnum;
echo "\n";
echo 'описание ';
echo $s->ip->{'inet-descr'};
echo "\n";
echo 'город ';
echo $s->ip->city;
echo "\n";
echo 'регион ';
echo $s->ip->region;
echo "\n";
echo 'округ ';
echo $s->ip->district;
echo "\n";
echo 'широта ';
echo $s->ip->lat;
echo "\n";
echo 'долгота ';
echo $s->ip->lng;

?>
28 марта 2009, 14:55

Генерация английского алфавита

<?php
/**
 * Генерация английского алфавита
 * автор: Nc_Soft
 * 10.03.09
 */

$letters=array();
for ($i=0; $i<26; $i++) {
	$letters[]=chr($i+65);
	$letters[]=chr($i+97);
}

print_r($letters);
?>
10 марта 2009, 13:01

Определение мобильного оператора

<?php
/**
 * Определение мобильного оператора
 * автор: Nc_Soft
 * Спасибо за помощь и критику Pиpиcу
 * 02.03.09
 */

/*-- ----------------------------
-- Table structure for oper
-- Таблица операторов
-- ----------------------------

CREATE TABLE `oper` (
  `id_oper` tinyint(4) unsigned NOT NULL auto_increment,
  `oper` varchar(255) NOT NULL,
  PRIMARY KEY  (`id_oper`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

--тут прописываем опсосов
INSERT INTO `oper` VALUES ('1', 'Megafon');
INSERT INTO `oper` VALUES ('2', 'Beeline');
INSERT INTO `oper` VALUES ('3', 'Utel');
INSERT INTO `oper` VALUES ('4', 'BWC');
INSERT INTO `oper` VALUES ('5', 'MTS');
INSERT INTO `oper` VALUES ('6', 'TELE2');
--итд

-- ----------------------------
-- Table structure for ip
-- Таблица ip адресов
-- ----------------------------

CREATE TABLE `ip` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `id_oper` tinyint(4) unsigned NOT NULL,
  `astart` int(11) unsigned NOT NULL,
  `aend` int(11) unsigned NOT NULL,
  PRIMARY KEY  (`id`),
  UNIQUE KEY `astart_aend` (`astart`,`aend`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

--диаппазоны (для примера вбито 7 диаппазонов мегафона)
INSERT INTO `ip` VALUES ('', '1', '1402275840', '1402276863');
INSERT INTO `ip` VALUES ('', '1', '1402273792', '1402275839');
INSERT INTO `ip` VALUES ('', '1', '1402277888', '1402278911');
INSERT INTO `ip` VALUES ('', '1', '1402279936', '1402280959');
INSERT INTO `ip` VALUES ('', '1', '1402281984', '1402283007');
INSERT INTO `ip` VALUES ('', '1', '1402284032', '1402285055');
INSERT INTO `ip` VALUES ('', '1', '1402286080', '1402287103');
--итд
*/

//теперь представим, что зашел человек с ip=83.149.16.32
//определим его оператора
$q=mysql_query("SELECT o.id_oper, o.oper FROM ip i
LEFT JOIN oper o ON i.id_oper=o.id_oper
WHERE INET_ATON('83.149.16.32') BETWEEN i.astart AND i.aend LIMIT 1
");
$q=mysql_fetch_row($q);

//посмотрим что получилось
print_r($q);

?>
2 марта 2009, 22:27

Защита от граббера

<?php
/**
* Защита от граббера
* автор: Nc_Soft
* 25.02.09
*/

//Полуавтоматический вариант, позволяет обнаружить подозрительные ип
if ( fsockopen($_SERVER['REMOTE_ADDR'] ,80 ,$err ,$errno ,1) )
echo 'Возможно, это граббер, так как открыт порт 80';

/*
Здесь приведена лишь методика определения граббера, конечно, это не надо делать при
каждом запросе к скрипту. Лучше иметь список часто обращающихся ип и прогнать 
их через этот способ. Решение о бане можно принять только обратившись к whois серверу, 
потому что порт 80 открыт не только у хостеров, но и порой у обычных юзеров.
*/
26 февраля 2009, 00:12

Jad генератор на основе ZipArchive

<?php
/**
 * Jad генератор на основе ZipArchive
 * автор: Nc_Soft
 * 13.02.09
 */
$file = 'test.jar';
$jad = '';

//создаем объект
$z = new ZipArchive();

if ($z->open($file)) {
	$fp = $z->getStream('META-INF/MANIFEST.MF');
	if(!$fp) exit("не удалось открыть манифест");

	//читаем данные
	while (!feof($fp)) {
		$jad .= fread($fp, 200);
	}

	fclose($fp);

	//дописываем что надо
	$jad .= "\nMIDlet-Jar-Size: ".filesize($file)."\nMIDlet-Jar-URL: $file";

	//сохраняем
	file_put_contents('test.jad', $jad);
}

//А вообще, можно извлечь манифест еще проще
echo file_get_contents("zip://$file#META-INF/MANIFEST.MF");
//http://ru.php.net/manual/en/function.ziparchive-getstream.php
?>
13 февраля 2009, 17:26

1+7=7?

<?php
echo (int) ((0.1 + 0.7) * 10); //7

/*никогда не приводите неизвестную дробь к целому!
http://ru.php.net/manual/ru/language.types.integer.php
*/
?>
12 февраля 2009, 01:26

Логарифмическое облако тегов

<?php
/**
 * Логарифмическое облако тегов
 * автор: Nc_Soft
 * 22.01.09
 */

/*
Допустим, имеем теги и частоту их встречаемости
тег1 5
тег2 6
тег3 9
тег4 2
тег5 8
тег6 13
тег7 1
тег8 16
....
*/

//эти данные обычно берутся из бд, тут же я проимитирую их массивом
$tags=array(
'тег1'=> 5,
'тег2'=> 6,
'тег3'=> 9,
'тег4'=> 2,
'тег5'=> 8,
'тег6'=> 13,
'тег7'=> 1,
'тег8'=> 16,
);

$minSize=10; //минимальный размер шрифта
$maxSize=26; //максимальный размер шрифта

$minWeight=min($tags); //минимальный вес тега
$maxWeight=max($tags); //максимальный вес тега

$tegi=array();

//вычислим размер шрифта тегов
foreach ($tags as $tag=>$tagWeight) {
	
	//шрифт по логарифмическому закону
	$font= floor( (log($tagWeight + 1) - log($minWeight + 1)) / (log($maxWeight + 1) - log($minWeight + 1)) * ($maxSize - $minSize) + $minSize );
	
	//добавим в массив
	$tegi[]='<a href="" style="font-size:'.$font.'px">'.$tag.'</a>';
}

//теперрь перетасуем и выведем
shuffle($tegi);

echo implode('<br />',$tegi);

/*
кому интресно что получилось могут запустить :)
*/

?>
22 января 2009, 09:06

Проверка email

<?php
/**
 * Проверка email
 * автор: Nc_Soft
 * 19.01.09
 */

//все еще изобретаете велосипеды?
//тогда мы идем к вам :)

if (filter_var('example@example.com', FILTER_VALIDATE_EMAIL)) {
	echo 'емаил верный<br />';
}

if (filter_var('_example@example.com', FILTER_VALIDATE_EMAIL)) {
	echo 'емаил неверный<br />';
}

?>
19 января 2009, 19:40

Переадресация с задержкой

<?php
/**
* Переадресация с задержкой
* автор: Nc_Soft
* 15.01.09
*/

header('Refresh: 3; URL=http://example.com');
echo 'Через 3 сек. вы будете перенаправлены на новую страницу.';
exit;
?>
15 января 2009, 14:38

Определение знака зодиака

<?php
/**
 * Определение знака зодиака
 * автор: Nc_Soft
 * 12.01.09
 */

//массив для сравнений
$zodiak=array(
'Oven'=>'Овен',
'Taurus'=>'Телец',
'Gemini'=>'Близнецы',
'Cancer'=>'Рак',
'Leo'=>'Лев',
'Virgo'=>'Дева',
'Libra'=>'Весы',
'Scorpion'=>'Скорпион',
'Sagittarius'=>'Стрелец',
'Capricorn'=>'Козерог',
'Aquarius'=>'Водолей',
'Fish'=>'Рыбы'
);

//функция опеределения
function zodiak($d,$m) {

	$d=sprintf('%02d',$d);
	$m=sprintf('%02d',$m);

	if (($m=='03' AND $d>20) OR ($m=='04' AND $d<21)) return 'Oven';
	if (($m=='04' AND $d>20) OR ($m=='05' AND $d<22)) return 'Taurus';
	if (($m=='05' AND $d>21) OR ($m=='06' AND $d<22)) return 'Gemini';
	if (($m=='06' AND $d>21) OR ($m=='07' AND $d<23)) return 'Cancer';
	if (($m=='07' AND $d>22) OR ($m=='08' AND $d<24)) return 'Leo';
	if (($m=='08' AND $d>23) OR ($m=='09' AND $d<24)) return 'Virgo';
	if (($m=='09' AND $d>23) OR ($m=='10' AND $d<24)) return 'Libra';
	if (($m=='10' AND $d>23) OR ($m=='11' AND $d<23)) return 'Scorpion';
	if (($m=='11' AND $d>22) OR ($m=='12' AND $d<22)) return 'Sagittarius';
	if (($m=='12' AND $d>21) OR ($m=='01' AND $d<19)) return 'Capricorn';
	if (($m=='01' AND $d>20) OR ($m=='02' AND $d<19)) return 'Aquarius';
	if (($m=='02' AND $d>18) OR ($m=='03' AND $d<21)) return 'Fish';

	return null;
}

//тестирование (пример для 3 декабря)
echo $zodiak[zodiak(3,12)]; //Стрелец

?>
12 января 2009, 08:26

Определениие возраста по дате рождения (mysql)

<?php
/**
 * Определениие возраста по дате рождения (mysql)
 * автор: Nc_Soft
 * 11.01.09 
 */

//Этот вариант дал протечку  на дате 1982-02-24 на 2 марта 2009 он выводит что челу 26 лет

/* поле даты должно иметь в базе тип DATE !! 
пример для даты произвольной даты 1984-08-25 */
echo mysql_result(
mysql_query("
SELECT DATE_FORMAT(DATE_SUB(FROM_DAYS(TO_DAYS(NOW()) - TO_DAYS('1984-08-25')), INTERVAL 1 MONTH ), '%y') as age
"
)
,0,0);

/*
Поэтому юзаем вариант Ририса
SELECT (YEAR(CURRENT_DATE) - YEAR(`birth`)) - (DAYOFYEAR(CURRENT_DATE) < DAYOFYEAR(`birth`)) as `age`
*/

?>
11 января 2009, 10:36

Постраничная навигация с ООП

<?php
/**
 * Постраничная навигация с ООП
 * автор: Nc_SOft
 * 08.01.09
 */


//класс навигатор представлен ниже, его лучше сохранить в отдельном файле
//пример использования: 1.навигация в массиве

//это массив 1,2,3,..,100
$arr=range(1,100);

//создаем навигатор
$n=new Navigator('',5);

//всего элементов
$all=count($arr);

//теперь возьмем 5 элементов из массива при помощи SPL
$larr=new LimitIterator(new ArrayIterator($arr), $n->start(), $n->pnumber);

//выводим элементы
echo '<div>';
foreach ($larr as $k=>$v) {
	if ($k) echo '<br />';
	echo $v;
}
echo '</div>';

//и печатаем навигацию
echo $n->navi($all);


//теперь пример с БД
//создаем навигатор
$n=new Navigator('',5);

//делаем запрос(например, к таблице юзеров id|login)
$q=mysql_query("SELECT SQL_CALC_FOUND_ROWS id,login FROM users ORDER BY id LIMIT {$n->start()}, $n->pnumber ");
$all=mysql_result(mysql_query("SELECT FOUND_ROWS()"),0,0);

while (false!==($res=mysql_fetch_assoc($q))) {
	print_r($res);
}

//навигация
echo $n->navi($all);




//а вот и сам навигатор, если есть идеи как его улучшить пишите
class Navigator {
	/**
	 * конструктор
	 *
	 */
	function __construct($script,$pnumber,$query='') {
		$this->script=$script;

		//если не задано имя скрипта, то используем текущее
		if (empty($script)) {
			$this->script=$_SERVER['SCRIPT_NAME'];
		}

		//элементов на страницу
		$this->pnumber=$pnumber;

		$this->query='';
		$this->or_query=$query;

		//если задана строка параметров
		if (is_array($query)) {
			foreach ($query as $k=>$v) {
				$this->query.='&'.$k.'='.urlencode($v);
			}
		}

		//обработка текущего номера страницы
		$this->page=isset($_GET['page']) ? (int)$_GET['page'] : 1;
	}

	/**
	 * Инициализация навигатора, вычесление стартовой позиции
	 */
	function start() {

		//вычисление стартовой позиции
		$this->start = $this->page * $this->pnumber - $this->pnumber;

		//обработка левых номеров
		if ($this->page < 1) {
			$this->page=1;
			$this->start=0;
		}

		return $this->start;
	}

	/**
	 * Печать навигатора
	 */
	function navi($all,$input=0) {

		//всего элементов
		$this->all=$all;

		//число страниц
		$this->num_pages=ceil($this->all/$this->pnumber);

		//если страниц более 5, то выводим форму
		if ($this->num_pages > 5) $input=1;

		//проверка корректности
		if ($this->page > $this->num_pages || $this->page < 1) {
			$this->page=1;
			$this->start=0;
		}

		//не печатаем навигатор, если всего одна страница
		if ($this->num_pages<2)
		return '';

		$buff='<div class="navi">';

		//блок вперед
		if ($this->page>1)
		$buff.='<a href="'.$this->script.'?page='.($this->page-1).$this->query.'"><</a>';
		else
		$buff.='<';

		//блок ссылок
		for($pr = '', $i =1; $i <= $this->num_pages; $i++) {
			$buff.=
			$pr=(($i == 1 || $i == $this->num_pages || abs($i-$this->page) < 2) ? ($i == $this->page ? " [$i] " : ' <a href="'.$this->script.'?page='.$i.$this->query.'">'.$i.'</a> ') : (($pr == ' ... ' || $pr == '')? '' : ' ... '));
		}

		//блок назад
		if ($this->page<$this->num_pages)
		$buff.='<a href="'.$this->script.'?page='.($this->page+1).$this->query.'">></a>';
		else
		$buff.='>';

		//печатаем форму с полем ввода (можно это убрать отсюда если не требуется)
		if ($input) {
			$buff.='<form style="margin:0" action="'.$this->script.'" method="get"><p style="margin:0">';

			$buff.='<input size="2" name="page" value="'.$this->page.'"/>';

			if (!empty($this->query)) {
				foreach ($this->or_query as $name=>$value) {
					$buff.='<input type="hidden" name="'.$name.'" value="'.htmlspecialchars($value).'" />';
				}
			}

			$buff.='<input type="submit" value=">>"/></p></form>';
		}

		$buff.='</div>';

		return $buff;
	}
}
8 января 2009, 19:01

Установка временной зоны в Mysql

<?php
/**
 * Установка временной зоны в Mysql
 * автор: Nc_Soft
 * 08.01.09
 */

/*если putenv('TZ=Europe/Moscow'); не помогает перевести время в Mysql, 
то можно попробовать вот такой способ
*/
mysql_query("SET LOCAL time_zone='+03:00'");

/*
тут время задается по Гринвичу, этот запрос надо сделать при коннекте к бд
*/
?>
8 января 2009, 18:15

Установка временной зоны

<?php
/**
 * Установка временной зоны
 * автор: Nc_Soft
 * 08.01.09
 */

/*очень часто приходится видеть такое
echo date('H:i:s'+time()*3600);
есть способ проще!
*/
putenv('TZ=Europe/Moscow');

/*
узнать свою зону можно через поисковик, нагуглилось за 5 секунд
http://www.cms4site.ru/ru-webmodules-datetime-zonetable.html
*/
?>
8 января 2009, 18:12

Создание символической ссылки на файл

<?php
/**
 * Создание символической ссылки на файл
 * автор: Nc_Soft
 * 03.01.09
 */

/*
Имеется некоторая защищенная директория (deny from all), в которой лежат файлы
1.mp3
2.mp3
3.mp3 итп
Задача выдать эти файлы с произвольным именем юзеру по запросу
*/

//защищенная директория
$private_dir=$_SERVER['DOCUMENT_ROOT'].'/private';

//создадим доступную директорию public с правами 777
$public_dir=$_SERVER['DOCUMENT_ROOT'].'/public';

/*в директорию public будем класть символические ссылки.
Обращаю внимание, что символические ссылки ничего не весят.
Допустим, мы хотим выдать ссылку на файл /private/1.mp3 в виде
/public/mega_hit_track.mp3
*/

//создаем символическую ссылку
if (symlink($private_dir.'/1.mp3', $public_dir.'/mega_hit_track.mp3')) {
	//выдаем ссылку юзеру
	echo '<a href="http://'.$_SERVER['HTTP_HOST'].'public/mega_hit_track.mp3">скачать</a>';
}
else {
	echo 'ошибка генерации ссылки';
}

/*в папке public создалась символическая ссылка 
mega_hit_track.mp3
обращение http://'.$_SERVER['HTTP_HOST'].'public/mega_hit_track.mp3
приведет к скачиванию статичного файла /private/1.mp3 из папки 

Преимущества символических ссылок:
-ссылки можно генерировать на лету
-можно сделать несколько разных ссылок на один и тот же файл
-с символическими ссылками можно работать как с файлами и каталогами (удаление/перемешение/переименование)

Недостатки:
-работает только в Linux
*/

?>
3 января 2009, 04:38

Определение запущенных процессов

<?php
/**
 * Определение запущенных процессов
 * автор: Nc_Soft
 * 03.01.09
 */

/*
Очень часто видео на сервере конвертируют по крону (потому что это очень ресурсоемкая процедура).
Для этого возникает необходимость узнать сколько ffmpeg'ов запущено.
Если запущено более 1 экземпляра конвертацию лучше отложить до следующего запуска
*/

//выполним такую команду и результат пихнем в $pslist
exec("ps aux | grep ffmpeg", $pslist);

/*строка, которая нас интересует выглядит как-то так
user   74080 95.1  0.6 32732 21788  ??  R     2:09AM   0:20.81 /usr/bin/ffmpeg
*/


//осталось только перебрать массив
foreach ($pslist as $r) {
	$v=preg_split('|\s+|', $r);
	if ($v[10] == '/usr/bin/ffmpeg') die('ffmpeg уже запущен, выходим');
}

//аналогично можно поступить с другими процессами, например с lame

?>
3 января 2009, 04:06

Использование preg_replace_callback в методе класса

<?php
/**
 * Использование preg_replace_callback в методе класса
 * автор: Nc_Soft
 * 03.01.09
 */

/*
Предположим, что надо сделать замену для смайлов
смайлы будут иметь вид <ЧИСЛО> и заменять это будем на <img src="/smile/ЧИСЛО.jpg" alt="" />
доп условия:
	-число замен не более 3
	-число в смайле должно соответствовать некоторому условию (в примере это диаппазон от 1 до 15)
*/

class Smile {

	//учитываем число замен
	private $smiles=0;

	//функция печати смайлов
	 function print_smiles($text) {
		return preg_replace_callback('|<(\d+)>|',array($this,'scb'),$text);
	}

	//функция обратного вызова для регулярки
	private function scb($v) {
		if ($this->smiles<3 && $v[1]>=1 && $v[1]<=15) {
			$this->smiles++;
			return '<img src="/smile/'.$v[1].'.jpg" alt="" />';
		}
		return $v[0];
	}
}

//пример
$s=new Smile();
echo $s->print_smiles('<1> <23><3><5><4>');

?>
3 января 2009, 03:56

Вывод файлов определенного типа при помощи SPL

<?php
/**
 * Вывод файлов определенного типа при помощи SPL
 * автор: Nc_Soft
 * 10.12.08
 */

/*напишем фильтр
для этого надо расширить FilterIterator, реализовав метод
accept()
*/
class F_FileIterator extends FilterIterator
{
	private $ext;
	private $it;

	function __construct(DirectoryIterator $it,$ext)
	{
		parent::__construct($it);
		$this->it=$it;
		$this->ext=$ext;
	}

	function accept()
	{
		return (pathinfo($this->current(),PATHINFO_EXTENSION)==$this->ext) ? true : false;
	}
}

//а теперь выведем из текущей директории только php файлы
$d=new F_FileIterator(new DirectoryIterator('./'), 'php');

foreach ($d as $v)
{
	echo "$v<br />\n";
}
?>
10 декабря 2008, 12:08

Подключение по https через CURL с посылкой сертификата

<?php
/**
 * Подкдючение по https через CURL с посылкой сертификата
 * автор: Nc_Soft
 * 19.11.08
 */

//!необходимо скачать сертификат ( в примере это WebMoneyCA.crt )

$ch=curl_init('https://w3s.webmoney.ru/asp/XMLInvoice.asp');
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)");
curl_setopt($ch, CURLOPT_CAINFO, 'WebMoneyCA.crt');
echo curl_exec($ch);

?>
19 ноября 2008, 20:38