Создайте ejabberd пользователя из PHP

Очень легкий иметь размеры...

В небольшом количестве кода обработки жесткого цикла, где я знаю, длина фиксируется , я использую массивы для того дополнительного крошечного бита микрооптимизации; массивы могут быть незначительно быстрее , если Вы используете индексатор / для формы - но IIRC полагают, что это зависит от типа данных в массиве. Но если Вы потребность для микрооптимизирования сохраните его простым и используйте List<T> и т.д.

, Конечно, это только применяется при чтении всех данных; словарь был бы более быстрым для основанных на ключе поисков.

Вот мои результаты с помощью "интервала" (второе число является контрольной суммой, чтобы проверить, что они все сделали ту же работу):

(отредактированный для исправления ошибки)

List/for: 1971ms (589725196)
Array/for: 1864ms (589725196)
List/foreach: 3054ms (589725196)
Array/foreach: 1860ms (589725196)

на основе тестовой буровой установки:

using System;
using System.Collections.Generic;
using System.Diagnostics;
static class Program
{
    static void Main()
    {
        List<int> list = new List<int>(6000000);
        Random rand = new Random(12345);
        for (int i = 0; i < 6000000; i++)
        {
            list.Add(rand.Next(5000));
        }
        int[] arr = list.ToArray();

        int chk = 0;
        Stopwatch watch = Stopwatch.StartNew();
        for (int rpt = 0; rpt < 100; rpt++)
        {
            int len = list.Count;
            for (int i = 0; i < len; i++)
            {
                chk += list[i];
            }
        }
        watch.Stop();
        Console.WriteLine("List/for: {0}ms ({1})", watch.ElapsedMilliseconds, chk);

        chk = 0;
        watch = Stopwatch.StartNew();
        for (int rpt = 0; rpt < 100; rpt++)
        {
            for (int i = 0; i < arr.Length; i++)
            {
                chk += arr[i];
            }
        }
        watch.Stop();
        Console.WriteLine("Array/for: {0}ms ({1})", watch.ElapsedMilliseconds, chk);

        chk = 0;
        watch = Stopwatch.StartNew();
        for (int rpt = 0; rpt < 100; rpt++)
        {
            foreach (int i in list)
            {
                chk += i;
            }
        }
        watch.Stop();
        Console.WriteLine("List/foreach: {0}ms ({1})", watch.ElapsedMilliseconds, chk);

        chk = 0;
        watch = Stopwatch.StartNew();
        for (int rpt = 0; rpt < 100; rpt++)
        {
            foreach (int i in arr)
            {
                chk += i;
            }
        }
        watch.Stop();
        Console.WriteLine("Array/foreach: {0}ms ({1})", watch.ElapsedMilliseconds, chk);

        Console.ReadLine();
    }
}
10
задан BoltClock 23 August 2011 в 23:23
поделиться

2 ответа

ejabberdctl, безусловно, самый простой в этом конкретном случае. Другие варианты:

  • Реализуйте полный клиентский XMPP в PHP (!)

  • Внедрите модуль в Erlang, который проксирует запросы: обмен данными PHP <--> Erlang должен осуществляться через сокет, и потребуется много маршалинга (! )

4
ответ дан 3 December 2019 в 18:34
поделиться

Here's my final solution:

Thanks to jldupont's advice that ejabberdctl would be the easiest solution, I pressed on through the obstacles I ran into and have a working solution.

By default, apache's user doesn't have the right privileges to successfully run ejabberdctl (and for good reason). So in order for it to work, you have to call it with sudo. But... sudo requires a password, which presents 2 problems:

  1. The apache user doesn't have a password.
  2. Even if it did, there's no way to enter it from PHP.

Solution (for Ubuntu) - add this line at the end of /etc/sudoers:

www-data ALL= (ejabberd) NOPASSWD: /usr/sbin/ejabberdctl

The path to the sudoers file and ejabberdctl may vary for other Linux distros. This allows apache's user (www-data) to run only ejabberdctl with elevated privileges and without requiring a password.

All that's left is the PHP code:

<?php
    $username = 'tester';
    $password = 'testerspassword';
    $node = 'myserver.com';
    exec('sudo -u ejabberd /usr/sbin/ejabberdctl register '.$username.' '.$node.' '.$password.' 2>&1',$output,$status);
    if($output == 0)
    {
        // Success!
    }
    else
    {
        // Failure, $output has the details
        echo '<pre>';
        foreach($output as $o)
        {
            echo $o."\n";
        }
        echo '</pre>';
    }
?>

Security

It's important to note that this does present a significant security risk even though you're only allowing one command to be run by www-data. If you use this approach, you need to make sure you protect the PHP code behind some sort of authentication so that not just anybody can make it execute. Beyond the obvious security risks, it could open your server up to a Denial of Service attack.

10
ответ дан 3 December 2019 в 18:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: