Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / PHP PECL - Как получить имя константы по ее значению? / 4 сообщений из 4, страница 1 из 1
24.11.2015, 09:34
    #39111690
Alibek B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
PHP PECL - Как получить имя константы по ее значению?
Я использую пакет php-radius и хотел бы использовать имя константы вместо ее значения (например возвращаемое radius_send_request).

В случае с PHP-классом можно было бы использовать Reflection API (new ReflectionClass, а затем getConstants).
Но я не знаю, какое имя класса нужно указывать для PECL-модуля.
Можно конечно скачать исходники PECL-модуля, из файла radlib.h заполнить ассоциативный массив и использовать его.
Но вдруг в PHP уже есть подобный ассоциативный массив?
________________________
Мы смотрим с оптимизмом...
...в оптический прицел.
...
Рейтинг: 0 / 0
24.11.2015, 09:40
    #39111698
r u
r u
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
PHP PECL - Как получить имя константы по ее значению?
Alibek B.,

get_defined_constants()

Alibek B.хотел бы использовать имя константы вместо ее значения
а зачем? в чем чуть такого желания?
...
Рейтинг: 0 / 0
24.11.2015, 10:17
    #39111760
Alibek B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
PHP PECL - Как получить имя константы по ее значению?
Чтобы в логах видеть имена типов пакетов и атрибутов.
Да и в клиентском коде бывает удобнее строки использовать, шаблоны RADIUS-пакетов у меня обычно в текстовых файлах хранятся.
...
Рейтинг: 0 / 0
24.11.2015, 10:32
    #39111790
Alibek B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
PHP PECL - Как получить имя константы по ее значению?
Сделал такой код:

Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
324.
325.
326.
327.
328.
329.
330.
331.
332.
333.
334.
335.
336.
337.
338.
339.
340.
341.
342.
343.
344.
345.
346.
347.
348.
349.
350.
351.
352.
353.
354.
355.
356.
357.
358.
359.
360.
361.
362.
363.
364.
365.
366.
367.
368.
369.
370.
371.
372.
373.
374.
375.
376.
377.
378.
379.
380.
381.
382.
383.
384.
385.
386.
387.
388.
389.
390.
391.
392.
393.
394.
395.
396.
397.
398.
399.
400.
401.
402.
403.
404.
405.
406.
407.
408.
409.
410.
411.
412.
413.
414.
415.
416.
417.
418.
419.
<?php

// Получить значение из ассоциированного массива
function _get($array, $key)
{
	if (!isset($array, $key)) return;
	if (empty($array)) return;
	if (is_array($array))
	{
		if (array_key_exists($key, $array)) return $array[$key];
	}
}

// Аналог функции NVL
function _nvl($expr, $null=null, $value=null)
{
	if (isset($expr))
	{
		return isset($value) ? $value : $expr;
	}
	else
	{
		return $null;
	}
}

// Модуль для работы с RADIUS-сервером
class Radius
{

	// Типы RADIUS-пакетов
	const RAD_ACCESS_REQUEST      = 1;
	const RAD_ACCESS_ACCEPT       = 2;
	const RAD_ACCESS_REJECT       = 3;
	const RAD_ACCOUNTING_REQUEST  = 4;
	const RAD_ACCOUNTING_RESPONSE = 5;
	const RAD_ACCOUNTING_STATUS   = 6;
	const RAD_ACCESS_CHALLENGE    = 11;
	const RAD_DISCONNECT_REQUEST  = 40;
	const RAD_DISCONNECT_ACCEPT   = 41;
	const RAD_DISCONNECT_REJECT   = 42;
	const RAD_COA_REQUEST         = 43;
	const RAD_COA_ACCEPT          = 44;
	const RAD_COA_ACK             = 44;
	const RAD_COA_REJECT          = 45;
	const RAD_COA_NAK             = 45;

	private $rad;

	// Режим отладки класса
	static public function debug($mode=null)
	{
		static $debug;
		if (isset($mode)) $debug = (boolean)$mode;
		return $debug;
	}

	// Получить или вернуть код пакета по имени
	static public function type($find, $reverse=false)
	{
		$ref = new ReflectionClass('Radius');
		$cl = $ref->getConstants();
		foreach ($cl as $name=>$value)
		{
			if ($reverse)
			{
				if ($find == $value) return $name;
			}
			else
			{
				if ($find == $name) return $value;
			}
		}
		$cl = get_defined_constants(true);
		if (array_key_exists('radius', $cl))
		{
			foreach ($cl['radius'] as $name=>$value)
			{
				if ($reverse)
				{
					if ($find == $value) return $name;
				}
				else
				{
					if ($find == $name) return $value;
				}
			}
		}
	}

	// Конструктор
	function __construct($template=null)
	{
		$rad = radius_auth_open();
		$cfg = _cfg('radius', true);
		$cfg = $cfg[$template];
		if (!radius_add_server($rad, $cfg['host'], $cfg['port'], $cfg['secret'], 3, 3))
		{
			trigger_error('RADIUS connect error:' . radius_strerror($rad), E_USER_NOTICE);
			return;
		}
		$this->dict();
		$this->rad = $rad;
	}

	// Деструктор
	function __destruct()
	{
		if (isset($this->rad))
		{
			radius_close($this->rad);
		}
	}

	// Загрузить RADIUS-словарь из файла
	static private function load($file)
	{
		$debug = static::debug();
		$fh = fopen($file, "r");
		if (!$fh) return;
		$files = array();
		$data = array('vendor'=>array(), 'attr'=>array());
		$vendor = null;
		if ($debug) echo "*debug: load dictionary $file\n";
		while (($line = fgets($fh)) !== false)
		{
			$line = trim($line);
			if (substr($line,0,1) == "#") $line = null;
			$items = preg_split("/[\s]+/", $line);
			if (count($items) > 1)
			{
				$cmd = strtolower($items[0]);
				$name = (_get($items, 1));
				$id = (_get($items, 2));
				$type = strtolower(_get($items, 3));
				$vid = (_get($items, 4));
				if ($cmd == '$include')
				{
					if ($debug) echo "*debug: add file $items[1]\n";
					$files[] = $items[1];
				}
				else
				{
					if     ($cmd == 'vendor')
					{
						if ($debug) echo "*debug: add vendor #$id $name\n";
						$data['vendor'][$name] = $id;
					}
					elseif ($cmd == 'begin-vendor')
					{
						if ($debug) echo "*debug: add vendor $name\n";
						$vendor = $name;
					}
					elseif ($cmd == 'end-vendor')
					{
						$vendor = null;
					}
					elseif ($cmd == 'attribute')
					{
						if (!isset($vid)) $vid = $vendor;
						if ($debug) echo "*debug: add attribute #$id $name (vendor $vid)\n";
						$data['attr'][$name] = array('name'=>$name, 'id'=>$id, 'type'=>$type, 'vendor'=>$vid);
					}
					elseif ($cmd == 'value')
					{
						if (array_key_exists($name, $data['attr']))
						{
							if ($debug) echo "*debug: add value #$type $id (attribute $name)\n";
							if (!array_key_exists('values', $data['attr'][$name])) $data['attr'][$name]['values'] = array();
							$data['attr'][$name]['values'][$id] = $type;
						}
					}
					elseif ($cmd == 'vendorattr')
					{
						$vid = (_get($items, 1));
						$name = (_get($items, 2));
						$id = (_get($items, 3));
						$type = strtolower(_get($items, 4));
						foreach ($data['vendor'] as $key=>$item)
						{
							if ((int)$vid == (int)$item)
							{
								if ($debug) echo "*debug: add attribute #$id $name (vendor $key)\n";
								$data['attr'][$name] = array('name'=>$name, 'id'=>$id, 'type'=>$type, 'vendor'=>$key);
								break;
							}
						}
					}
					elseif ($cmd == 'vendorvalue')
					{
						$vid = (_get($items, 1));
						$name = (_get($items, 2));
						$id = (_get($items, 3));
						$type = strtolower(_get($items, 4));
						if (array_key_exists($name, $data['attr']))
						{
							if ($debug) echo "*debug: add value #$type $id (attribute $name)\n";
							if (!array_key_exists('values', $data['attr'][$name])) $data['attr'][$name]['values'] = array();
							$data['attr'][$name]['values'][$id] = $type;
						}
					}
				}
			}
		}
		fclose($fh);
		if ($debug) echo "*debug: load done\n";
		return array('data'=>$data, 'file'=>$files);
	}

	// Обратится к RADIUS-словарю
	static public function dict($attr=null, $reverse=false)
	{
		static $dict;
		if (!isset($dict))
		{
			$base = "/etc/raddb";
			$files = array('dictionary'=>false);
			$dict = array();
			$n = count($files);
			while ($n > 0)
			{
				foreach ($files as $file=>$state)
				{
					if ($state)
					{
						$n--;
					}
					else
					{
						$ret = static::load("$base/$file");
						$files[$file] = true;
						$n--;
						if (isset($ret))
						{
							foreach ($ret['data']['vendor'] as $key=>$item) $dict['vendor'][$key] = $item;
							foreach ($ret['data']['attr'] as $key=>$item) $dict['attr'][$key] = $item;
							foreach ($ret['file'] as $file)
							{
								if (!array_key_exists($file, $files))
								{
									$files[$file] = false;
									$n++;
								}
							}
						}
					}
				}
			}
		}
		if (isset($attr))
		{
			if ($reverse)
			{
				$a = null;
				$v = null;
				if (is_array($attr))
				{
					$a = _get($attr,'id');
					$v = _get($attr,'vid');
				}
				else
				{
					$a = $attr;
					if (is_string($a) && array_key_exists($a, $dict['attr'])) $a = $dict['attr'][$a]['id'];
				}
				$ret = null;
				foreach ($dict['attr'] as $item)
				{
					$ia = _get($item,'id');
					$iv = _get($item,'vendor');
					if (isset($iv)) $iv = _get($dict['vendor'],$iv);
					if (($ia == $a) && (_nvl($iv,0) == _nvl($v,0)))
					{
						$ret = $item;
						$ret['vid'] = $iv;
						break;
					}
				}
				return $ret;
			}
			else
			{
				if (!isset($vendor)) $vendor = '';
				if (array_key_exists($attr, $dict['attr']))
				{
					$ret = $dict['attr'][$attr];
					$ret['vid'] = null;
					if (isset($ret['vendor']) && array_key_exists($ret['vendor'], $dict['vendor']))
					{
						$ret['vid'] = $dict['vendor'][$ret['vendor']];
					}
					return $ret;
				}
			}
		}
	}

	// Выполнить RADIUS-запрос и получить ответ
	function request($avpair=null, $type=RADIUS_ACCESS_REQUEST)
	{
		if (!isset($avpair)) return;
		if (!is_array($avpair)) return;
		if (empty($avpair)) return;

		$debug = static::debug();
		$rad = $this->rad;
		$t = static::type($type,true);
		if ($debug) echo "*debug: create request #$type" . (isset($t) ? " ($t)" : "") . "\n";
		if (!radius_create_request($rad, $type))
		{
			if ($debug) echo "*debug: create request fail: " . radius_strerror($rad) . "\n";
			trigger_error('RADIUS create request error:' . radius_strerror($rad), E_USER_NOTICE);
			return;
		}
		foreach ($avpair as $a=>$v)
		{
			$ret = null;
			$a = static::dict($a);
			if ($debug) echo "*debug: attribute $a[name] (#$a[id], $a[type]" . (isset($a['vid']) ? ", vendor $a[vendor]" : "") . ") := $v" . ((isset($a['values']) && array_key_exists($v, $a['values'])) ? " (#$a[values])" : "") . "\n";
			if (isset($a['values']) && array_key_exists($v, $a['values'])) $v = $a['values'];
			if (isset($a['vid']))
			{
				if ($a['type'] == "integer")
				{
					$ret = radius_put_vendor_int($rad, $a['vid'], $a['id'], $v);
				}
				elseif ($a['type'] == "string")
				{
					$ret = radius_put_vendor_string($rad, $a['vid'], $a['id'], $v);
				}
				elseif ($a['type'] == "ipaddr")
				{
					$ret = radius_put_vendor_addr($rad, $a['vid'], $a['id'], $v);
				}
				else
				{
					$ret = radius_put_vendor_attr($rad, $a['vid'], $a['id'], $v);
				}
			}
			else
			{
				if ($a['type'] == "integer")
				{
					$ret = radius_put_int($rad, $a['id'], $v);
				}
				elseif ($a['type'] == "string")
				{
					$ret = radius_put_string($rad, $a['id'], $v);
				}
				elseif ($a['type'] == "ipaddr")
				{
					$ret = radius_put_addr($rad, $a['id'], $v);
				}
				else
				{
					$ret = radius_put_attr($rad, $a['id'], $v);
				}
			}
			if (!$ret)
			{
				trigger_error('RADIUS set request error:' . radius_strerror($rad), E_USER_NOTICE);
				return;
			}
		}

		$ret = radius_send_request($rad);
		if ($ret === false)
		{
			if ($debug) echo "*debug: send request fail: " . radius_strerror($rad) . "\n";
			trigger_error('RADIUS send request error:' . radius_strerror($rad), E_USER_NOTICE);
			return;
		}
		$t = static::type($ret,true);
		if ($debug) echo "*debug: response #$type" . (isset($t) ? " ($t)" : "") . "\n";

		$reply = array();
		while ($res = radius_get_attr($rad))
		{
			if ($res['attr'] == RADIUS_VENDOR_SPECIFIC)
			{
				$vsa = radius_get_vendor_attr($res['data']);
				$a = static::dict(array('id'=>$vsa['attr'], 'vid'=>$vsa['vendor']));
				$v = $vsa['data'];
			}
			else
			{
				$a = static::dict($res['attr']);
				$v = $res['data'];
			}
			if (isset($a['values']))
			{
				foreach ($a['values'] as $key=>$item)
				{
					if ($item == $v)
					{
						$v = $key;
						break;
					}
				}
			}
			if ($debug) echo "*debug: reply $a[name] (#$a[id], $a[type]" . (isset($a['vid']) ? ", vendor $a[vendor]" : "") . ") := $v" . ((isset($a['values']) && array_key_exists($v, $a['values'])) ? " (#$a[values])" : "") . "\n";
			$reply[$a['name']] = $v;
		}

		return array($ret=>$reply);
	}

	// Сбросить подключение
	function reconnect($session=null, $username=null, $ip=null)
	{
		$req = array();
		$req['RBN-Context_Name'] = 'local';
		if (isset($session)) $req['Acct-Session-Id'] = $session;
		if (isset($username)) $req['User-Name'] = $username;
		if (isset($ip)) $req['Framed-IP-Address'] = $ip;
		return $this->request($req, static::RAD_DISCONNECT_REQUEST);
	}

}




Используется так:
Код: php
1.
2.
3.
$rad = new Radius('billing');
Radius::debug(true);
dump($rad->reconnect($auth->session, $auth->username, $auth->ip));



Но этот код почему-то не работает для RAD_DISCONNECT_REQUEST, выдает ошибку "No User or Chap Password attributes given".
Скачал исходники пакета, за эту ошибку отвечает такой фрагмент кода:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
	if (h->request[POS_CODE] == RAD_ACCOUNTING_REQUEST
	    || h->request[POS_CODE] == RAD_COA_REQUEST
	    || h->request[POS_CODE] == RAD_COA_ACK
	    || h->request[POS_CODE] == RAD_COA_NAK
	    || h->request[POS_CODE] == RAD_DISCONNECT_REQUEST
	    || h->request[POS_CODE] == RAD_DISCONNECT_ACK
	    || h->request[POS_CODE] == RAD_DISCONNECT_NAK) {
		/* Make sure no password given */
		if (h->pass_pos || h->chap_pass) {
			generr(h, "User or Chap Password in non-access request");
			return -1;
		}
	} else {
		/* Make sure the user gave us a password */
		if (h->pass_pos == 0 && !h->chap_pass) {
			generr(h, "No User or Chap Password attributes given");
			return -1;
		}
		if (h->pass_pos != 0 && h->chap_pass) {
			generr(h, "Both User and Chap Password attributes given");
			return -1;
		}
	}


И вроде бы для RAD_DISCONNECT_REQUEST пароль не должен требоваться.
Но почему-то требуется.

Еще смущает, что тут и в get_defined_constants() константа определена как RADIUS_DISCONNECT_REQUEST, в то время как в файле radlib.h она задана следующим образом:
Код: plaintext
#define RAD_DISCONNECT_REQUEST		40
...
Рейтинг: 0 / 0
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / PHP PECL - Как получить имя константы по ее значению? / 4 сообщений из 4, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]