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

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

get_defined_constants()

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

Код: 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
4 сообщений из 4, страница 1 из 1
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / PHP PECL - Как получить имя константы по ее значению?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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