[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: заморожено пока
Krevedko

#Помещаем данные в массив
$tags = array( 'title' => 'Мой сайт',
'description' => 'Сайт лучшего програмера',
'link_1' => 'Главная',
'link_2' => 'О себе',
'link_3' => 'Связь'
);

$tags = serialize($tags);

#Сериализованный массив записываем в файл
file_put_contents('../setup/tags.txt', $tags);

..............


Потом в нужном месте пишем

#Достаем сериализованный массив из файла
$photos = file_get_contents('../setup/tags.txt');
$tags = unserialize($tags);




Спустя 7 минут, 15 секунд (19.11.2009 - 22:47) twin написал(а):
Ну кое что это лучше чем ничего.
1. Комменты будем писать в одном стиле. Как у меня. Я буду топать ногами и рвать из груди волосы, если это будет нарушаться. Мы собираемся делать коммерческие продукты и аккуратность тут приоритетна.
2. Если у тебя редактор вставляет табуляцию, помудри чего нибудь с ним. Видишь же как все разьехалось.
3. Я просил написать скрипт вывода дескрипшенов, а не формирования файлов. Это к тому, что ты подошел к заданию безответственно.

Можете обзывать меня (про себя biggrin.gif ) ворчуном, придирой, или по матери - мне плевать. Порядок должен быть. И я думаю что он будет.

Спустя 7 часов, 34 минуты, 26 секунд (20.11.2009 - 06:22) profesor написал(а):
Цитата
Нужно написать скрипт, который будет доставать из текстовых файлов в директории setup данные и помещать в свои теги. Title, description и так далее)). В зависимости от выбранной страницы.



Почему не помещать в файл(ы) общие описание Title, description и так далее

например для Title что то "Курсы PHP программистов"

а в базу данных каждой статье, странице свои личные Title, description
потом просто вытаскивать их по id и к общим добавлять еще и личные, чтоб получалось

например для Title что то "Курсы PHP программистов :: Приступаем Урок № 1"
или "Курсы PHP программистов :: Продолжаем Урок № 2"

Спустя 31 минута, 25 секунд (20.11.2009 - 06:53) Alehandr написал(а):
Выложу класс конфигуратора своего проекта:

<?php

class
Configurator_Core {

public static function Load($name) {
if (is_file(APP_ROOT . 'config' . DS . $name . EXT)){
return include(APP_ROOT . 'config' . DS . $name . EXT);
}
if (is_file(CORE_ROOT . 'config' . DS . $name . EXT)){
return include(CORE_ROOT . 'config' . DS . $name . EXT);
}
return array();
}

public static function Save($name, $array) {
file_put_contents(APP_ROOT . 'config' . DS . $name . EXT,
"<?php\n\nreturn " .
preg_replace_callback("/\n([\s]+)/ui", array('Configurator', 'SaveCallback'), var_export($array, true)) .
";\n");
}

private static function SaveCallback($matches) {
return "\n" . str_replace(" ", "\t", $matches[1]);
}

}


if (!defined('CONFIGURATOR_CLASS')) {
class Configurator extends Configurator_Core { }
}



И пример файла конфигурации для вашего:

<?php

return array(
'title' => 'Site title',
'description' => 'My site',
'keywords' => 'keywords',
);


Спустя 3 часа, 34 минуты, 34 секунды (20.11.2009 - 10:28) stepan написал(а):
Цитата (twin @ 19.11.2009 - 17:58)
global $GET;

А мы разве пользуемся глобальными переменными?

Спустя 13 секунд (20.11.2009 - 10:28) Shturman написал(а):
Цитата (twin @ 20.11.2009 - 07:12)
twin
Выкладывай новую версию, не правь старые. Иначе мы запутаемся так.

Хорошо, дублирую сюда (правда, старую версию уже не вернуть smile.gif )

В папку /skins/setup помещен файл "descriptions" с содержимым вида:

mod|news
rem|razdel-1
id|anyID
page|index
lishnee|lishnee

Пишем следующий скрипт:

/**
* Read file 'descriptions' and put into massive
* Читаем из файла 'descriptions' и помещаем в массив
*/

$file_name = "./skins/setup/descriptions";
$file = fopen($file_name, "r");

while($string = fgets($file, filesize($file_name))){
$temp = explode("|", $string);
/**
* Comment next line if additional variables in file $GET are resolved
* Закомментируйте следующую строку, если разрешены дополнительные переменные в массиве $GET
*/

if(isset($GET[$temp[0]]))
$GET[$temp[0]] = $temp[1];
}

Вывод:

/**
* Test output: massive $RESULT
* Тестовый вывод: массив $RESULT
*/

echo "<hr>Содержимое массива \$GET<br>";
foreach($GET as $par => $val)
echo "<br>$par = $val";

Результат можно посмотреть тут

оффтоп: что за спаны в коде проскакивают? Ошибка форума?

Спустя 8 минут, 14 секунд (20.11.2009 - 10:36) twin написал(а):
Цитата
А мы разве пользуемся глобальными переменными?

Мы - да. Другой вопрос что подразумевать под глобальными переменными. Если это по поводу register_globals то разумеется нет. Читай первый урок. А если это объяваление глобальной переменной в функции - почему бы и нет. Паранойя - не лучшая черта программиста на мой взгляд. Одна деталька. Переменные, объявляемые глобальными, мы будем писать в верхнем регистре, дабы их как то обозначить.
Shturman
Ну вот опять немного не то. Зачем нам сложности с разделителями и парсингом. А если кто то захочет сделать такой тайтл
Уроки PHP | Урок №3 Курс №1 от Twina | Макет сайта | Часть третья.
? Почитай про сериализацию.

Спустя 21 минута, 41 секунда (20.11.2009 - 10:58) Shturman написал(а):
Ладно, тогда все сводится к простейшему:
1. В файле "descriptions" сериализованный массив изначального вида

a:4:{s:3:"mod";s:6:"news
";s:3:"rem";s:10:"razdel-1
";s:2:"id";s:7:"anyID
";s:4:"page";s:7:"index
";}

Наш скрипт тогда выглядит так:

/**
* Read file 'descriptions' and unserialize data
* Читаем из файла 'descriptions' и рассериализуем массив
*/

$file_name = "./skins/setup/descriptions";
$file = fopen($file_name, "r");
$string = fread($file, filesize($file_name));
$GET = unserialize($string);
fclose($file);

/**
* Test output: massive $GET
* Тестовый вывод: массив $GET
*/


echo "<hr>Содержимое массива \$GET<br>";
foreach($GET as $par => $val)
echo "<br>$par = $val";

Спустя 58 минут, 48 секунд (20.11.2009 - 11:57) krasilich написал(а):
Допусти в файле лежит сериализованый массив вида

/**
*Setup array
*/

$setup = array(['title'] => 'title',
[
'desc'] => 'description',
[
'keyword'] => 'keyword');


Элементы можем добавить, когда в этом будет небходимость

Читаем массив,


/**
* Read file 'descriptions.txt' and unserialize data
*/

$file_name = "./skins/setup/descriptions.txt";
$string = file_get_contents($file_name);
$setup = unserialize($string);

/**
*Init setup variables
*/

foreach($desc as $key => $value)
{
$$key = $value;
}


Имеем набор переменных, которые будут вставлены в наш шаблон

Спустя 49 секунд (20.11.2009 - 11:58) twin написал(а):
Shturman
Вот, молодца. Уже горяче.
Но.
Во первых, для чтения файла гораздо удобнее пользоваться функцией file_get_contents()
Во вторых, зачем перебор массива в цикле, если можно просто обратиться сразу к нужному элементу? Не надь.
В третьих. Нужно вывести три значения для тайтлов, дескрипшенов и кейвордов. У тебя одно. Нужно использовать многомерный массив.

soniclord
Цитата
Может мой вопрос покажется странным....но:
php намного быстрее работает с базами данных чем с файлами, так почему бы не использовать бд?

Вопрос закономерный. Но БД это отдельный сервер. Гонять два сервера из за пары слов - нерентабельно. Ну и верно заметил see_man. Это не быстрее вовсе.

Спустя 11 минут, 40 секунд (20.11.2009 - 12:09) stepan написал(а):
Вот мой вариант

main.txt

/**
*Returning of entrance parametres
*Возвращение входных параметров
*/


return array (
'news' => array (
'title' => 'Новости',
'keywords' => 'Новости',
'description' => 'Здесь находятся только горячии новости',
),

'gallery' => array (
'title' => 'Галерея',
'keywords' => 'Галерея',
'description' => 'Посетите нашу галерею',
),
);


index.php

/**
*Reading of an adjusting file
*Чтение установочного файла
*/


$main = eval ( file_get_contents ( './skins/setup/main.txt' ) );

/**
*Distribution of values in variables
*Распределение значений в переменные
*/


$title = $main[ $GET['mod'] ]['title'];
$keywords = $main[ $GET['mod'] ]['keywords'];
$description = $main[ $GET['mod'] ]['description'];

Спустя 12 минут, 44 секунды (20.11.2009 - 12:22) krasilich написал(а):
Десиарилизуем массив

/**
* Read file 'descriptions.txt' and unserialize data
*/

$file_name = "./skins/setup/descriptions.txt";
$string = file_get_contents($file_name);
$setup = unserialize($string);

Пишем в шаблон
index.tpl

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta
http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title><?php
echo $setup['title']; ?></title>
<meta
name="keywords" content="<?php echo $setup['keywords']; ?>" />
<meta
name="description" content="<?php echo $setup['description']; ?>" />
</head>
<body>
<?php
echo $content; ?>
</body>
</html>

Спустя 15 минут, 29 секунд (20.11.2009 - 12:37) krasilich написал(а):
десиарилизация.

/**
* Read file 'descriptions.txt' and unserialize data
*/

$file_name = "./skins/setup/".$GET['mod']."_".$GET['rem']."_".$GET['id'].".txt";
if(!file_exists($file_name))
$file_name = "./skins/setup/".$GET['mod']."_".$GET['rem'].".txt";
$string = file_get_contents($file_name);
$setup = unserialize($string);

Спустя 58 минут, 2 секунды (20.11.2009 - 13:36) twin написал(а):
stepan
Цитата
Я не пойму каким образом пользоваться этой unserialize ()
Если точно ей обязательно надо вообще пользоваться.

Эта функция позволяет преобразовать любой (в частности многомерный) массив в строковое представление. То есть в обычную строку.
А значит мы спокойно можем записать структурированные данные в текстовый файл.
Потом считать информацию, рассериализовать и вывести нужные переменные уже так, как ты и сделал.
Что это даст.
Во первых, вся нужная информация будет находиться в одном файле. Её там совсем не много, по этому размер файла не имеет особого значения.
А с одним массивом работать удобнее, чем с несколькими разными.
Во вторых, инклюд работает медленнее, чем file_get_contents(). И хотя потребуется время на рассериализацию, это все равно удобнее.
По поводу скорости можно провести тест кстати. Кто возьмется?

А самое главное - файлы php по определению служат для хранения исполняемого кода, а не для хранения данных. По этому Кесарю - кесарево.
Данные лучше хранить в текстовых файлах.

Спустя 45 минут, 44 секунды (20.11.2009 - 14:21) krasilich написал(а):
Итак:
структура базы

CREATE TABLE `test` (
`title` varchar(255) collate utf8_bin NOT NULL,
`keywords` varchar(255) collate utf8_bin NOT NULL,
`description` varchar(255) collate utf8_bin NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;


Скрипт

set_time_limit(0);
/**
* Number of iteration
*/

$i_max = 1000;
echo 'Количество итераций: '.$i_max.'<br>';

/**
* Get the mysql result
*/

$starttime = microtime(1);
for($i = 0; $i <= $i_max; $i++)
{
mysql_connect('localhost', 'root', '');
mysql_select_db('test');
$result = mysql_query('SELECT * FROM test');
$array = mysql_fetch_assoc($result);
mysql_close();
}
$endtime = microtime(1);
$time = $endtime - $starttime;
echo 'Данные из базы обрабатывались: '.$time = round($time, 5).'сек.<br>';


/**
* Write a file with serialize array
*/

$str_arr = serialize($array);
file_put_contents('array.txt', $str_arr);


/**
* Get the file result
*/

$starttime = microtime(1);
for($i = 0; $i <= $i_max; $i++)
{
$string = file_get_contents('array.txt');
$array = unserialize($string);
}
$endtime = microtime(1);
$time = $endtime - $starttime;
echo 'Данные из файла обрабатывались: '.$time = round($time, 5).'сек.<br>';


Ну и собственно мои результаты

Количество итераций: 1000
Данные из базы обрабатывались: 8.33538сек.
Данные из файла обрабатывались: 2.72021сек.</span>

Спустя 5 минут, 5 секунд (20.11.2009 - 14:26) twin написал(а):
Здорово. Спасибо. Но тестировать надо было немного не это.
А именно, что быстрее - include() и исполнение кода (вариант stepan'a) или file_get_contents() с последующей рассериализацией.
С базой и так все было ясно.
Но пример очень поучительный.

Спустя 58 минут, 26 секунд (20.11.2009 - 15:25) krasilich написал(а):
Еще один тест.
Файл test.txt

return array ('title' => 'title',
'keywords' => 'keywords',
'description' => 'description',
);


Файл test_php.txt

<?php
return array ('title' => 'title',
'keywords' => 'keywords',
'description' => 'description',
);

?>


Скрипт

set_time_limit(0);
/**
* Number of iteration
*/

$i_max = 100;
echo 'Количество итераций: '.$i_max.'<br>';

/**
* Get the eval result
*/

$starttime = microtime(1);
for($i = 0; $i <= $i_max; $i++)
{
$array = eval(file_get_contents ( 'test.txt'));
}
$endtime = microtime(1);
$time = $endtime - $starttime;
echo 'eval() Данные обрабатывались: '.$time = round($time, 5).'сек.<br>';


/**
* Get the include result
*/

$starttime = microtime(1);
for($i = 0; $i <= $i_max; $i++)
{
$array = include 'test_php.txt';
}
$endtime = microtime(1);
$time = $endtime - $starttime;
echo 'include Данные обрабатывались: '.$time = round($time, 5).'сек.<br>';


/**
* Write a file with serialize array
*/

$str_arr = serialize($array);
file_put_contents('array.txt', $str_arr);


/**
* Get the serialize result
*/

$starttime = microtime(1);
for($i = 0; $i <= $i_max; $i++)
{
$string = file_get_contents('array.txt');
$array = unserialize($string);
}
$endtime = microtime(1);
$time = $endtime - $starttime;
echo 'unserialize() Данные обрабатывались: '.$time = round($time, 5).'сек.<br>';



Результат

Количество итераций: 1000
eval() Данные обрабатывались: 4.34442сек.
include Данные обрабатывались: 3.21808сек.
unserialize() Данные обрабатывались: 2.79525сек.

Спустя 52 минуты, 59 секунд (20.11.2009 - 16:18) stepan написал(а):
Цитата (twin @ 20.11.2009 - 10:36)
Данные лучше хранить в текстовых файлах.

Убедил

И спасибо за объяснение
вот что сделал:
двумерный массив сериализовал и записал его в файл


/**
*Serialize of the data and file recording
*Сериализация данных и запись в файл
*/


$ser = serialize (
array (
'news' => array (
'title' => 'Новости',
'keywords' => 'Новости',
'description' => 'Здесь находятся только горячии новости',
),

'gallery' => array (
'title' => 'Галерея',
'keywords' => 'Галерея',
'description' => 'Посетите нашу галерею',
),
)
);


file_put_contents ( './skins/setup/main.txt', $se );


В файле получилась вот такая бяка:
a:2:{s:4:"news";a:3:{s:5:"title";s:14:"Новости";s:8:"keywords";s:14:"Новости";s:11:"description";s:72:"Здесь находятся только горячии новости";}
s:7:"gallery";a:3:{s:5:"title";s:14:"Галерея";s:8:"keywords";s:14:"Галерея";s:11:"description";s:40:"Посетите нашу галерею";}}


и index.php поправил

/**
*Reading of an adjusting file
*Чтение установочного файла
*/


$get = file_get_contents ( './skins/setup/main.txt' );
$main = unserialize( $get ) ;

/**
*Distribution of values in variables
*Распределение значений в переменные
*/


$title = $main[ $GET['mod'] ]['title'];
$keywords = $main[ $GET['mod'] ]['keywords'];
$description = $main[ $GET['mod'] ]['description'];

/**
* We connect the main template of a site
* Подключаем главный шаблон сайта
*/


отличная вещь приму на заметку cool.gif

Спустя 8 часов, 45 минут, 40 секунд (21.11.2009 - 01:03) twin написал(а):
Если ты тут впервые, прочитай это!!!

На прошлом уроке мы сообща решили вопрос с динамической сменой тайтлов и метатегов. Функция получилась такой

/**
* Function of formation of meta-tags
* Функция формирования мета-тегов
*/


function getMeta($tag)
{
if(!file_exists(ROOT .'/skins/setup/meta.txt'))
die('There is no file with the data for meta tags');

static $meta;
global $GET;

if(empty($meta))
{
$meta = unserialize(file_get_contents (ROOT .'/skins/setup/meta.txt'));

if(!is_array($meta))
die('Meta-data are not established');
}

return $meta[$GET['mod']][$tag];
}


Поместим её в файл default и продолжим.

Чего нам теперь остро не хватает. Раз на прошлом занятии завели речь об админке, давайте её и организуем.

Админка будет находиться в отдельной директории, пусть она так и будет называться - admin. В неё поместим индекс и модули, которые нужно администрировать. То есть мы имеем в корне директорию admin, в ней индекс и три каталога
1. news
2. gellery
3. setup
с индексом в каждой.
А что бы не потерять пути, пропишем в конфигу еще одну константу

/**
* Establishes a physical path to a root directory of a script
* Устанавливает физический путь до корневой директории скрипта
*/

define('ROOT', str_replace('\\', '/', $_SERVER['DOCUMENT_ROOT']));

Ну и немного изменим функцию генерации ссылок, что бы отделить мухи от котлет. То есть ссылки админки от простых ссылок.

/**
* Function of formation of GET-parametres
* Функция формирования GET-параметров
*/


function href()
{
global $GET;
$href = '';
$arg = func_get_args();

if(defined('ADMIN'))
$href = '/admin';

foreach($arg as $var)
{
$get = explode('=', $var);

if(array_key_exists($get[0], $GET))
$GET[$get[0]] = $get[1];
else
die('The variable <b>'. $get[0] .'</b> is not defined');
}

foreach($GET as $var => $val)
if(isset($val) && MOD_REWRITE == 'on')
$href .= '/'. $val;
elseif(!empty($val))
$href .= '&'. $var .'='. $val;


if(MOD_REWRITE == 'on')
return HOST . trim($href, '/');
else
return
HOST .'?'. trim($href, '&');
}

Теперь нам достаточно в индексе админки определить константу ADMIN и все ссылки пойдут на директорию admin. Правда нужно немного дополнить .htaccess

AddDefaultCharset UTF-8
php_flag magic_quotes_gpc Off
php_flag magic_quotes_runtime Off
php_flag register_globals Off
php_flag expose_php off
ErrorDocument 401 /401.html
ErrorDocument 403 /403.html
ErrorDocument 404 /404.html

# php_value error_reporting 2047
# php_value error_log "Z:/home/test.den/www/log/error.log"
# php_flag log_errors on
# php_flag display_errors off

RewriteEngine on

RewriteRule ^admin/(.*)$ admin/index.php?route=$1 [L,QSA]
RewriteCond %{REQUEST_URI} !^/admin
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?route=$1 [L,QSA]</span>


Ну а что бы убедиться, что это все красиво работает, снабдим этот "шедевр" навигацией. Для этого в каталоге tpl сделаем шаблон меню. Выглядет очень просто - две ссылки:
menu.tpl
<a href="<?[SPAN=darling]php[/SPAN] echo href('mod=news'); ?>">Новости</a> | <a href="<?[SPAN=darling]php[/SPAN] echo href('mod=gallery'); ?>">Галерея</a>

подключим в оба индекса (в индексе админки укажем полный путь)
главный индекс
	
/**
* Generation of the menu of navigation
* Генерация меню навигации
*/

ob_start();
include './skins/tpl/menu.tpl';
$menu = ob_get_contents();
ob_end_clean();

индекс админки (полностью)
<?[SPAN=darling]php[/SPAN]
/**
* We establish the charset and level of errors
* Устанавливаем кодировку и уровень ошибок
*/

header("Content-Type: text/html; charset=utf-8");
error_reporting(E_ALL);

/**
* Installation of a key of access to files
* Установка ключа доступа к файлам
*/

define('KEY', true);

/**
* The administrator-panel identifier
* Идентификатор админ-панели
*/

define('ADMIN', true);

ob_start();

/**
* We connect a configuration file
* Подключаем конфигурационный файл
*/

include '../config.php';

/**
* We connect a file of initialization of variables
* Подключаем файл инициализации переменных
*/


include ROOT .'/variables.php';

/**
* We connect a file of the general functions
* Подключаем файл общих функций
*/

include ROOT .'/libs/default.php';

$title = getMeta('title');
$keywords = getMeta('keywords');
$description = getMeta('description');

/**
* The switch of modules
* Переключатель модулей
*/

switch ($GET['mod'])
{
case 'news':
include './news/index.php';
break;

case 'gallery':
include './gallery/index.php';
break;

default:
include './news/index.php';
}


$content = ob_get_contents();
ob_end_clean();


/**
* Generation of the menu of navigation
* Генерация меню навигации
*/

ob_start();
include ROOT .'/skins/tpl/menu.tpl';
$menu = ob_get_contents();
ob_end_clean();

/**
* We connect the main template of a site
* Подключаем главный шаблон сайта
*/

include ROOT .'/skins/index.tpl';

и выведем меню в шаблон.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta
http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title><?
[SPAN=darling]php[/SPAN] echo $title; ?></title>
<meta
name="keywords" content="<?[SPAN=darling]php[/SPAN] echo $keywords; ?>" />
<meta
name="description" content="<?[SPAN=darling]php[/SPAN] echo $description; ?>" />
</head>
<body>
<?
[SPAN=darling]php[/SPAN] echo $menu; ?><br />
<?
[SPAN=darling]php[/SPAN] echo $content; ?>
</body>
</html>



Теперь можно запустить и поэксперементировать. Посмотреть как меняются тайтлы и метатеги, как работают ссылки, отключить-включить реврайт.
Изучайте, скрипт в аттаче.

А задание будет таким. Нужно нам теперь админку закрыть паролем.
Какие предложения?

В следующем уроке мы наконец то начнем помаленьку понимать, что же это такое - MVC.

Спустя 25 минут, 3 секунды (21.11.2009 - 01:28) twin написал(а):
Да, кстати.
Посмотреть можно здесь и админку здесь.

Спустя 6 минут, 46 секунд (21.11.2009 - 01:35) Krevedko написал(а):
Ну форма ввода, сверяет логин-пароль, если все нормально, то создается сессия.

А еще у Попова biggrin.gif видел форму ввода...там виндовое окошко. Вот как-то упустил посмотреть как оно сделано.

Спустя 12 минут, 21 секунда (21.11.2009 - 01:48) krasilich написал(а):
смотрим мой вариант
index.php

/**
*Check, if user are loged as login
*/

if(empty($_SESSION['admin']))
admin_login();

/**
*Login function
*/

function admin_login ()
{
if(count($_POST) > 0) //if we have data in POST array
{
$login = isset($_POST['admin_login'])?$_POST['admin_login']:null;
$pass = isset($_POST['admin_pass'])?$_POST['admin_pass']:null;

if($login == ADMIN_LOGIN && $pass == ADMIN_PASS)
{
$_SESSION['admin'] = time();
header('Location: /admin');
}
else
{
exit('Login or password is incorrect')
}
}

else
{
include 'admin_login.tpl';
exit;
}
}


Логин и пароль определны как константы в конфиге

Спустя 12 минут, 24 секунды (21.11.2009 - 02:00) Gabriel написал(а):
twin
говоря об админке мне в голову первым делом приходит вопрос сколько будет людей имеющих туда доступ? если несколько то будут ли у них разные права пользования ( добавление, удаление, редактирование разделов ) если да то без БД никуда. если будет просто несколько человек можно как для себя любимого указать данные для входа в файле smile.gif а при х неправильных вводов данных отправлять куда нибудь и не подпускать больше на х времени.
see_man
извиняюсь время позднее прохлопал ушами

Спустя 1 минута, 43 секунды (21.11.2009 - 02:02) Krevedko написал(а):
if(count($_POST) > 0)     


хм...почему не isset ?

Gabriel - да константы -то понятно. что их трудно создать чтоли..

Цитата
а при х неправильных вводов данных отправлять куда нибудь и не подпускать больше на х времени.


и отправлять тоже на х biggrin.gif

Спустя 1 минута, 13 секунд (21.11.2009 - 02:03) krasilich написал(а):
Gabriel
Цитата

я пропустил определение констант?

Я, думаю, Вы в состоянии определить две константы самостоятельно.

Krevedko
Цитата

хм...почему не isset ?


Мне больше нравиться такой вариант, хотя isset тоже вожможен

Цитата

отправлять тоже на х biggrin.gif


На $x...

Спустя 2 минуты, 14 секунд (21.11.2009 - 02:05) RequIem написал(а):
2twin
Global $n1, $n2, $n3;

Требует немного больше времени чем
$GLOBAL['n1']


Может лучше юзать именно через глобальную переменную?
Не спорю, запутаней.

Спустя 5 минут, 44 секунды (21.11.2009 - 02:11) twin написал(а):
see_man
Не годится.
1. Самая главная ошибка - пароль в явном виде. Пароль обязательно хэшируется, где бы он ни был.
2. Всего один вариант логин-пароль. А если администраторов несколько и кого то уволили? Придется всем сообщать о смене пароля. Моветон.
3. Вообще принято определение функции писать выше вызова.
4. Переменные нужно объявлять явно.
5. В таких делах равенство должно быть строгим.
6. для чего в сессии время? Достаточно true.
7. exit применяется только для дебагинга. Ну за редким исключением. А если я просто ошибся? Новое окно открывать?
8. А вот последний эксит вообще ни к чему. Скрипт и сам спокойно остановится.
9. Это должно быть частью сайта, а не отдельной фишкой. Я сделал основу - внедряй.
10. Комменты на русском где? Плевать я хотел на условности, мы для людей работаем. И публика в основном у нас русскоязычная.


Критики больше чем строчек в коде biggrin.gif
Исправляй.

Gabriel
Не спрашивай, а предлагай.

RequIem
Цитата
Не спорю, запутаней.

Вот именно. Читабельность хоть маломальская все таки важна. А времени на пару переменных уйдет пшик. Мы же этим не собираемся злоупотреблять.

Спустя 2 минуты, 42 секунды (21.11.2009 - 02:14) MainVoid написал(а):
Мне кажется надо учитывать, что админов может быть несколько.
И предлагаю хранить данные админов в БД, в общей таблице пользователей (ведь в нашем проекте будут и простые смертные?), но в отдельной группе (админы).
Верно?

Спустя 9 минут, 27 секунд (21.11.2009 - 02:23) RequIem написал(а):
Во сновном использовал следующий код:

if (!isset($_SESSION['inside']) AND isset($_POST['log_in_name']) AND isset($_POST['log_in_pass'])) {
@mysql_connect("$dbadres", "$dbuser", "$dbpass");
@mysql_select_db("$dbname");
$log_in_name = mysql_escape_string(substr($_POST['log_in_name'], 0, 16));
$log_in_pass = md5(md5(substr($_POST['log_in_pass'], 0, 32)));

$log_in_query = mysql_query(" SELECT `name`,
`id1`, `id2`, `id3`
FROM `ie_users`
WHERE name='"
.$log_in_name."' AND pass='".$log_in_pass."'");

if (@mysql_num_rows($log_in_query)==1) {
$log_in_row = mysql_fetch_array($log_in_query);
$_SESSION['id1'] = $log_in_row['id1'];
$_SESSION['id2'] = $log_in_row['id2'];
$_SESSION['id3'] = $log_in_row['id3'];
$_SESSION['name'] = $log_in_row['name'];
$_SESSION['inside'] = 1;
} else {
$global_error[] = 'Пользователь не найден';
}
}


Не учтены ошибки (лог ошибок), не хватает пару проверок для полной картины. (счётчик/блок на перебор паролей)
Вместо id1 и т.д. можно присвоить и date и емаил и т.д.
В зависимости от того что надо.

Спустя 2 минуты, 12 секунд (21.11.2009 - 02:25) twin написал(а):
Цитата
И предлагаю хранить данные админов в БД,

Не очень хорошая идея имхо. База при всем своем удобстве вещь все таки более уязвимая, чем файлы. И уж тем более плохо в одной таблице с юзерами.
А админка - сердце сайта. Администраторов обычно немного. По этому лучше всё таки такие вещи хранить там, куда доступ избранным. Я бы предложил прямо в конфиге.

Спустя 2 минуты, 53 секунды (21.11.2009 - 02:28) RequIem написал(а):
2twin
А если взять в расчёт "регистрацию пользователей"?
Если регистрацию не делать, то фиг с БД, будет даже быстрее.
ну а с регистрацией без БД никуда.

Не спорю, админ данные можно отдельно от пользователей хранить.

2Krevedko
В столь простом коде Николай разберётся быстро. Я написал для общего обозрения, вовсе не для "изучения кода"

Спустя 8 минут, 55 секунд (21.11.2009 - 02:37) krasilich написал(а):

/**
*функция входа в админку
*/

function admin_login ()
{
if(count($_POST) > 0) //if we have data in POST array
{
$login = isset($_POST['admin_login'])?$_POST['admin_login']:null;
$pass = isset($_POST['admin_pass'])?md5($_POST['admin_pass']):null;

/**
*Считываем в массив пары логин-пароль
*/

$admin = file('admin.txt');

foreach($admin as $value)
{
$value = explode(':', $value);
if($login === $value[0] && $pass === $value[1])
{
$_SESSION['admin'] = true;
header('Location: /admin');
}
else
{
include 'admin_login.tpl';
}
}

else
{
include 'admin_login.tpl';
}
}


/**
*Проверяем, вошел ли пользователь как админ
*/

if(empty($_SESSION['admin']))
admin_login();



Файл admin.txt

admin1:ab23141cdb345dcab45acd2232dce
admin2:ec23145de35dcab45acd34dce34dc</span>

Спустя 1 минута, 13 секунд (21.11.2009 - 02:38) twin написал(а):
RequIem
Тоже щас разнесу в пух и прах.
1. Переменные функцией isset можно проверять кучей, через запятую. Зачем такая лыжа из условий и функций...
2. Переменные в кавычках - на грани нарушения семантики. К тому же нарушается читабельность и в 4 раза возрастает время обработки.
3. Собаки только для отладки. Ошибки надо логировать.
4. substr() на кой там ляд...
5. Двойной хэш думаешь страшнее одинарного? Сильно заблуждаешься. Ничуть.
6. mysql_fetch_array() забудь. Это юзалось еще в 3-й версии PHP
7. На стиль обрати внимание. И убери табуляторы.
8. Где комменты????!!?!?!!!!??? mad.gif mad.gif mad.gif
9. Почему разброд? Где интеграция? Давайте уже привыкать делать одно дело. Сообща.
10. Ну и то, что зря ИМХО в базе, я написал выще.


Спустя 12 минут, 1 секунда (21.11.2009 - 02:50) twin написал(а):
Цитата (Krevedko @ 20.11.2009 - 23:26)
щас Николай тебе вставит...за отсутствие комментов, за собачки итд ))

Как в воду глядел. Я к чему эти строгости. Программирование, если оно на высоком уровне, требует самодисциплины. Комменты этому очень способствуют. К тому же если это профессиональная деятельность, продукт должен быть качественным. Расхолаживаться тут никак не дозволено.

see_man
Уже лучше. Но с логикой не все гладко.
И опять нет интеграции. Пока не привыкнем писать в общей схеме - толку не будет. Даже время на разбор тратить не хочу. Сделать нужно так, что бы я мог спокойно прикрутить к сайту, который у меня на локалке. Котрый должен быть у тебя. И у всех. Который в аттаче первого поста.

Спустя 18 минут, 38 секунд (21.11.2009 - 03:09) twin написал(а):
Цитата
substr для обрезания строки, дабы не делать толстый запрос (если пост с кучей символов)
Хэш по алгоритму mb5 из любой кучи символов все равно выйдет на 32. Зачем еще и резать...
Цитата
Двойной хеш я просто не убрал когда копировал кусок кода, по сути толку не больше чем от одинарного.

Я то этого не знаю. И компютер не знает. Мы с ним думаем, чято это ты специально так сделал. smile.gif
Цитата
Что со стилем не так я не понял, ни одного табулятора там нету.

Да, с табом поторопился, подумал в запросе у тебя расползлось. А стиль... Операторы пробелом не выделяешь, отступа от края нету, запрос странно как то написан... В общем то конечно неплохо, но должно быть даже не хорошо, а отлично.

Про камменты уже написал. А код на рассмотрение хорошо конечно, но он должен быть полезным, а не сам по себе.

Спустя 14 минут, 17 секунд (21.11.2009 - 03:23) krasilich написал(а):

/**
* Массив с парами логин-пароль, для администраторов
* Ключ - логин, значение - мд5 хеш пароля
* pass = '123123'
*/

$admins_login = array('admin' => '4297f44b13955235245b2497399d7a93');

/**
* Функция входа для администратора
*/

function admin_login ()
{
global $admins_login;
if(count($_POST) > 0)
{
$login_post = isset($_POST['admin_login'])?$_POST['admin_login']:null;
$pass_post = isset($_POST['admin_pass'])?md5($_POST['admin_pass']):null;

foreach($admins_login as $login => $pass)
{
if($login_post === $login && $pass_post === $pass)
{
$_SESSION['admin'] = true;
header('Location: /admin');
}
}

include ROOT .'/skins/tpl/admin_login.tpl';
}
else
{
include ROOT .'/skins/tpl/admin_login.tpl';
}
}

/**
* Вошел ли пользователь как админ?
*/

if(!isset($_SESSION['admin'])) admin_login();


Есть проблема. Если Не определена переменна $_SESSION['admin'] - выводиться форма для входа, а после нее и весь контент главной страницы.
Как решить, есть варианты?

P.S. twin, какая у Вас среда разработки?

Спустя 32 минуты, 40 секунд (21.11.2009 - 03:56) twin написал(а):
Цитата
P.S. twin, какая у Вас среда разработки?

На ты пожалуйста. Что значит среда разработки? Голова и руки... Редактор имеешь ввиду? Я двумя пользуюсь NOTEPAD++ и дримвейвер. Последний только как редактор, даже не разбирался в его мульках.
Я вообще считаю, что кодить надо руками, а не отладчиками.

Вариант твой вполне устраивает как основа, принимается. Завтра выложу интеграцию и продолжение.

Спустя 31 минута, 28 секунд (21.11.2009 - 04:27) krasilich написал(а):
Вот вариант, который у меня работает.

index.php

if(!isset($_SESSION['admin']))
{
include 'admin_pass.php'; //Файл с массивом паролей

/**
* Функция входа для администратора
*/

function admin_login ()
{
global $admins_login;

if(count($_POST) > 0)
{
$login_post = isset($_POST['admin_login'])?$_POST['admin_login']:null;
$pass_post = isset($_POST['admin_pass'])?md5($_POST['admin_pass']):null;

foreach($admins_login as $login => $pass)
{
if($login_post === $login && $pass_post === $pass)
{
$_SESSION['admin'] = true;
header('Location: /admin');
}
}

include ROOT .'/skins/tpl/admin_login.tpl';
}
else
{
include ROOT .'/skins/tpl/admin_login.tpl';
}
}


ob_start();
admin_login();
$content = ob_get_contents();
ob_end_clean();
}
else
{
ob_start();
//основной контент страницы
$content = ob_get_contents();
ob_end_clean();
}


admin_pass.php

/**
* Массив с парами логин-пароль, для администраторов
* Ключ - логин, значение - мд5 хеш пароля
* pass = '123123'
*/

$admins_login = array('admin' => '4297f44b13955235245b2497399d7a93');


admin_login.tpl

<form action="" method="POST">
<label>
логин: <input type="text" name="admin_login" /></label><br />
<label>
пароль: <input type="text" name="admin_pass" /></label><br />
<input
type="submit" />
</form>



Спустя 4 часа, 37 минут, 26 секунд (21.11.2009 - 09:05) Shturman написал(а):
2twin
Есть еще вариант - если идея устроит, за выходные оформлю в коде.

Собсно, идея: файл, в котором просто перечисляются имена админов. Каждому админу сопоставляется файл личных настроек.
Таким образом очень просто реализовать даже уровень доступа каждого админа и при необходимости заблокировать уволенного.

Кстати, с md5 можно еще побаловаться:
Вставить, скажем, между 5-м и 6-м символом рандомное число. А при проверке, соответствеенно, вырезать его.

P.S. где-то я так уже делал... Только с БД.

Спустя 30 минут, 35 секунд (21.11.2009 - 09:35) twin написал(а):
Shturman
Цитата
Может пригодиться для ограничения входа по времени, если админ, уходя, забыл нажать "выход". Мало ли с какой машины он заходил.

Вообще время жизни сессии по умолчанию обычно 24 минуты. Нам пока достаточно и этого, хотя за идею спасибо.

Есть еще вариант - если идея устроит, за выходные оформлю в коде.
С удовольствием посмотрим. smile.gif
И хотя на данном этапе нас больше интересует спартанский минимум - хорошие идеи всегда в цене.


Спустя 4 часа, 22 минуты, 46 секунд (21.11.2009 - 13:58) AvroN написал(а):
А если скомбинировать? сделать пару что-то типа "главных админов", их логины и хеш пароли хранить в массивах в конфиге, а всех остальных в БД и при авторизации проверять сначала массивы конфигов, а потом уже БД. и Плюс привилегии для "главных" админов сделать больше чем тех кого в БД добавляют, и еще нада сделать проверку чтоб при регистрации в бд не попал пользователь с именем админа и тп, тип проверка от подделок?

Спустя 33 минуты, 36 секунд (21.11.2009 - 14:32) krasilich написал(а):
Цитата

у меня ошибка Warning: include(ROOT/config.php) [function.include]: failed to open stream: No such file or directory


Это у twinа в коде ошибка, в индексном файле админки для подключения конфига используеться конствнта ROOT, которая определена в том же конфиге. Я просто заменил эту строчку

include ROOT.'/config.php';
на
include './config.php';

Спустя 8 часов, 57 минут, 23 секунды (21.11.2009 - 23:29) tata написал(а):
Цитата
/**
*Serialize of the data and file recording
*Сериализация данных и запись в файл
*/

$ser = serialize (
array (
'news' => array (
'title' => 'Новости',
'keywords' => 'Новости',
'description' => 'Здесь находятся только горячии новости',
),
'gallery' => array (
'title' => 'Галерея',
'keywords' => 'Галерея',
'description' => 'Посетите нашу галерею',
),
)
);

file_put_contents ( './skins/setup/main.txt', $se );


ПРавильно ли я поняла, что в последней строке должно быть $ser ?
И что с этим делать? выполнить как отдельный скрипт?

Спустя 36 минут, 38 секунд (22.11.2009 - 00:06) tata написал(а):
Kerlyk , спасибо за подробный ответ smile.gif

Цитата
Очень приятно видеть в наших рядах девушку)))

Спасибо:) Только девушка до пятницы кроме аббревиатуры РНР об этом ничего не знала, т.ч. задает идиотские вопросы, извините.

Цитата
/**
*Distribution of values in variables
*Распределение значений в переменные
*/

$title = $main[ $GET['mod'] ]['title'];
$keywords = $main[ $GET['mod'] ]['keywords'];
$description = $main[ $GET['mod'] ]['description'];



Мы в переменных объявили $GET - массив, $main - двумерный массив, первый идекс $GET['mod'] - в нашем примере он должен принимать либо значение 'news' либо 'gellery'? а где определяется, какое именно значение у него?

Спустя 1 час, 27 минут, 23 секунды (22.11.2009 - 01:33) bret написал(а):
Для ротатора имхо тогда уже изящнее было бы
case 'news':
case 'gallery':
include './modules/'.$GET["mod"].'s/index.php';
break;
default:
include './modules/news/index.php';
break;

Я вот подумал:
а) почему мы в двух индексах используем два одинаковых ротатора?
б) почему мы вообще используем два индекса? Админка в индексе главном, безусловно, усложнит код, но как быть с расширяемостью системы в текущем виде?
в) вроде как нет необходимости хранить админов отдельно от "смертных" юзеров. Почему бы не создать файл users.txt с сериализованной информацией о логинах, md5-паролях и уровнях доступа (на начальном этапе хотя бы "админ/не_админ")?

Спустя 30 минут, 9 секунд (22.11.2009 - 02:03) twin написал(а):
bret
Хороший вопрос. Ну давайте попробуем сделать иначе. Хотя я не вижу смысла. Это все равно разные файлы. Ну и даже не принимая это в расчет - я не вижу другой схемы, Предлогайте...

Спустя 10 минут, 17 секунд (22.11.2009 - 02:14) bret написал(а):
А ещё внезапнопоявившиеся бесконечные и непонятные мне ob_start()'ы, и множесто tpl'ов sad.gif
С утра сяду за вдумчивое понимае и оптимизацию...

Спустя 1 минута, 10 секунд (22.11.2009 - 02:15) krasilich написал(а):
Можно админку реализовать как модуль.
Тогда не нужно будет использовать два индекса...

Что касается хранения паролей, я думаю что пароли не стоит хранить в текстовом файла, даже в зашифрованом виде.
Я думаю, что вариант с массивом наиболее удобен как для редактирования,
так и с точки зрения защиты информации.

Спустя 2 минуты, 9 секунд (22.11.2009 - 02:17) krasilich написал(а):
Цитата

внезапнопоявившиеся бесконечные и непонятные мне ob_start()'ы, и множесто tpl'ов


Может есть необходимость написать шаблонизатор?

Спустя 1 час, 40 минут, 24 секунды (22.11.2009 - 03:57) Kerlyk написал(а):
bret
Спокойнее. Admin-ка на то и админка, чтобы стоять отдельно от пользователей. По-моему, удобно ваять представление для админов (с наворотами и функционалом) отдельно от представления для пользователей.
Так это нас избавит от бесконечных IF()-ов.

По поводу ротатоа - вариант. Но разницы особой нет.

И кстати, советую всем, дабы избавиться от путанницы, перейти на повсеместное использование 'gallery', а не gellery, galary, gelery и т.п.

Спустя 6 часов, 41 минута, 45 секунд (22.11.2009 - 10:39) bret написал(а):
При варианте с монтированием админки в главный индекс нам нужно добавить один элемент в массив $get (например, $get['action']). Тогда по появлению этого самого action мы и будем манипулировать контентом (несомненно, при наличии админ-флага). IF'ы, конечно, добавятся, но я считаю это меньше кровью (а если мы будем вводить ещё и группу модераторов, то от IFов нам всё равно никуда не деться). Одним из важных качеств нашей системы, я считаю, есть расширяемость - добавляя новый модуль разработчику как можно меньше надо думать о том, что надо "добавить папку с модулем, и строчку с модулем в ротатор на индексе главном, и строчку с модулем в индексе админском, и папку с модулем в папке админа"

Цитата (see_man @ 22.11.2009 - 01:15)
Я думаю, что вариант с массивом наиболее удобен как для редактирования,
так и с точки зрения защиты информации.

С учетом того, что пользователи - достаточно динамичный народец, имхо, нет смысла сажать их в относительно статичный config.php
Хранить админов отдельно от пользователей - это как минимум лишняя пассворд-проверка

Вобщем, надо, чтобы "мы посовещались и twin решил" smile.gif

Спустя 1 час, 58 секунд (22.11.2009 - 11:40) tata написал(а):
Цитата
Замени на include '../config.php';

мне помогло - были ошибки, аналогичные SaNtA
Вопрос: у меня ошибки вываливаются на экран в ядовито-оранжевом цвете, а логов в виде файлов нет. Это потому, что у нас закомментаренный
# php_value error_log "Z:/home/twintmp.ru/www/log/error.log" ?
Т.е. лог либо на экран, либо в файл - а одновременно и экран и файл можно?

Спустя 2 минуты, 9 секунд (22.11.2009 - 11:42) twin написал(а):
Цитата
И кстати, советую всем, дабы избавиться от путанницы, перейти на повсеместное использование 'gallery', а не gellery, galary, gelery и т.п.

Спасибо, опять я где то скопипастил... Сейчас найду и исправлю.

Что касаемо
Цитата
При варианте с монтированием админки в главный индекс нам нужно добавить один элемент в массив $get
разумеется это проще, но мой опыт подсказывает мне, что доступ в админ-панель должен быть автономным.
Кроме безопасности тут есть некоторые удобства, до которых я еще не дошел в объяснениях.
Цитата
С учетом того, что пользователи - достаточно динамичный народец, имхо, нет смысла сажать их в относительно статичный config.php
Хранить админов отдельно от пользователей - это как минимум лишняя пассворд-проверка
позволю себе не согласиться. Это тоже вопросы безопасности.
Дело все в доступах. Если жулик вдруг сумеет распчатать базу (зарекаться глупо), то он узнает только хэши паролей пользователей. Ну пусть колупается. Доступ к админ-панели он не сможет получить по определению.

А вот если он получит доступ к ФC, то тогда ему станут изестны данные коннекта, что автоматически означает, что он имеет полный доступ к бд.

По этому ИМХО доступы в админ-панель лучше хранить отдельно от бд.

Цитата
Вобщем, надо, чтобы "мы посовещались и twin решил"

Совершенно верно, я не претендую на роль гуру, но выбрать оптимальный вариант из предложенных вполне в состоянии. И буду стараться обосновывать свой выбор.

Спустя 7 минут, 53 секунды (22.11.2009 - 11:50) SaNtA написал(а):
Цитата
Т.е. лог либо на экран, либо в файл - а одновременно и экран и файл можно?

Да, это будет намного удобней, либо, чтоб все не видели какие у нас ошибки, просто в браузере писало: Обнаружены ошибки, они записаны в фаил error.log
Как я понимаю, это возможно сделать условием в index файле

Спустя 51 секунда (22.11.2009 - 11:51) tata написал(а):
twin, сравнила свои скрипты с Вашими из архива.
когда мы частями дополняли главный индекс, то прямо в него вставили чтение из установочного файла и распределение в переменные, а Вы - с помощью функции meta, которая "живет" в другом месте?

Приводить свои скрипты - к Вашему виду?

Спустя 1 час, 27 минут, 13 секунд (22.11.2009 - 13:18) twin написал(а):
Цитата
Приводить свои скрипты - к Вашему виду?

Да. Вы поймите одно - эти скрипты рождаются именно здесь. В них наверняка есть ошибки, давайте вместе их исправим.

Я надеюсь, что эти скрипты будут рождаться с вашей помощью, а не как догма.

Когда мы придем к тому, что все и всех устраивает, начнутся более другие, серьёзные задачи.
За денажку. smile.gif

Спустя 5 минут, 33 секунды (22.11.2009 - 13:24) twin написал(а):
Цитата
Да, это будет намного удобней, либо, чтоб все не видели какие у нас ошибки, просто в браузере писало: Обнаружены ошибки, они записаны в фаил error.log
позволю себе не согласится.
Ошибки на стадии разработки хочется видеть сразу. Окарал - получи по морде. Лог открывать и анализировать - лишняя трата времени.
Вообще наша сверхзадача добиться того, что бы в лог писались только несанкционированные действия (ошибки, вызванные попытками взлома). А все остальное должно работать как часы.

Спустя 13 минут, 52 секунды (22.11.2009 - 13:37) Shturman написал(а):
Так, где-то у нас косяк... С Апачем разобрался, gallery везде поправил, причесал табуляцию и т.п.
На свою локалку скинул twin-овский архивчик, чтобы не растекаться, так сказать, мысию по древу и не спорить о разном. Так вот, смотрите, в строке запрос:

http://94.73.194.179/gallery/2/3/4

вывод:

Array ( [mod] => gallery [rem] => 2 [id] => 3 [page] => 4 )

Теперь второй запрос:

http://94.73.194.179/news/2/3/4

вывод:

Array ( [mod] => gallery [rem] => 2 [id] => 3 [page] => 4 )

Что не так? Все, вроде, проверил - и в массиве все нормально, и в конфигах, и в индексах...

P.S. Да поломайте кто-нить этот форум! Спаны задолбали mad.gif

Спустя 12 минут, 15 секунд (22.11.2009 - 13:50) Shturman написал(а):
Кстати, в админке все нормально работает (если, конечно, пути предварительно поправить wink.gif ).
http://94.73.194.179/admin
Но тоже самое, в $GET всегда первый элемент gallery

Спустя 10 минут, 39 секунд (22.11.2009 - 14:00) Kerlyk написал(а):
Shturman, это где-то у вас косяк. У меня при таком запросе
--localsite--/news/2/3/4
Array ( [mod] => news [rem] => 2 [id] => 3 [page] => 4 )
Проверьте правильность switch-а в файле variables.php.

К слову, вот сам файл (рабочая версия):

<?php

/**
* The block of initialization and processing of entering variables
* Блок инициализации и обработки входящих переменных
*
@author IT studio IRBIS-team
*
@copyright © 2009 IRBIS-team
*/
/////////////////////////////////////////////////////////

/**
* Generation of page of an error at access out of system
* Генерация страницы ошибки при доступе вне системы
*/

if(!defined('KEY'))
{
header("HTTP/1.1 404 Not Found");
header("X-Powered-By: ");
exit(file_get_contents('./404.html'));
}

/**
* Array of variables for GET-parametres
* Массив переменных для GET-параметров
*/

$GET = array(
'mod' => 'news',
'rem' => 0,
'id' => 0,
'page' => 0,
);


/**
* Initialization of variables GET-parametres
* Инициализация переменных GET-параметров
*/

if(!empty($_GET['route']) && MOD_REWRITE == 'on')
{
$get = explode('/', trim($_GET['route'], '/'));
$i = 0;

foreach($GET as $var => $val)
{
if(!empty($get[$i]))
$GET[$var] = $get[$i];

++
$i;
}
}

elseif(count($_GET))
{
foreach($GET as $var => $val)
if(!empty($_GET[$var]))
$GET[$var] = $_GET[$var];
}
?>

Спустя 2 часа, 11 минут, 9 секунд (22.11.2009 - 16:12) Argnist написал(а):
а разве это нормально, что меню у нас ведет на http://twinkurs/news/0/0/0, нули эти совсем не похожи на ЧПУ)

Спустя 23 минуты, 25 секунд (22.11.2009 - 16:35) Shturman написал(а):
Вычислил, что косяк у меня родом из функции href... роюсь дальше.

Спустя 2 часа, 44 минуты, 58 секунд (22.11.2009 - 19:20) Guest написал(а):
Можно вопрос а что практически нам дает использование ob_start(); ???

Спустя 1 час, 45 секунд (22.11.2009 - 20:21) twin написал(а):
Цитата
Но тоже самое, в $GET всегда первый элемент gallery

Это вовсе не косяк. Дело в том, что переменная $GET у нас объявлена глобальной. А соответственно она меняется на протяжении работы скрипта. Это как раз тот момент, почему прогеры боятся использовать глобальные переменные. Потому что считают это путаницей. Просто нужно аккуратнее и знать, что она глобальная. Я по этому и сделал её в верхнем регистре $GET.

Теперь по существу. А зачем ты смотришь print_r($GET)? Тебе что то понадобилось из этой переменной? Ты смотришь её по итогам работы , а по итогам элемент mod примет значение, которое последним было переданно в функцию. Поменяй местами ссылки и убедишься.
Но нам то она уже не нужна по итогам, пусть в ней будет все что угодно)))

Цитата
Можно вопрос а что практически нам дает использование ob_start(); ???

Это буфферизация. У неё есть масса плюсов.
1. Не нужно озадачиваться с порядком следования заголовков. Можно даже вывод сделать выше хидера. Буфферизация все приведет в порядок.
2. Скрипт сначала отрабатывает полностью, а уже потом идет сброс результатов в поток. Это несколько ровнее, а значит аккуратнее.
3. Ну и самое главное. Мы можем собрать весь вывод в одну переменную и вывести её там, где нам нужно. В частности в главный шаблон.

Спустя 6 минут, 39 секунд (22.11.2009 - 20:27) glock18 написал(а):
Цитата
2. Скрипт сначала отрабатывает полностью, а уже потом идет сброс результатов в поток. Это несколько ровнее, а значит аккуратнее.


на самом деле сброс вывода всегда делается только после того, как обработка закончится. если только не стоит директива implicit_flush, или вызвана одна из функций flush, implicit_flush

Спустя 1 час, 46 минут, 9 секунд (22.11.2009 - 22:13) Krevedko написал(а):
сделал. все работает. теперь осталось разобраться как оно работает )

я кстати понял, что мы наверное сайт-галерею делаем biggrin.gif

ЗЫ А почему файлы имеют ресширение tpl (темплейт)..это ж вроде в смарти применяется. Почему не html ?

Спустя 29 минут, 58 секунд (22.11.2009 - 22:43) Shturman написал(а):
Так, ладно, отчитаюсь. Только, чур, палками не бить wink.gif

Итак:
1. Был создан скриптик, который создает мниатюрную файловую БД. (понравилась мне сериализация, однако! biggrin.gif )

/**
* Make admins list-file
* Создаем файл-список админов
*/


$aaa = Array('admin' => 0, 'subadmin' => 0);
fwrite(fopen('./admin.list', 'w'), serialize($aaa));

/**
* Make customize files
* Создаем файлы с пользовательскими настройками
*/


$bbb = Array(
'login' => 'admin',
'password' => md5('parol'),
'style' => 'silver.css',
'rules' => '1'
);
fwrite(fopen('./customize/admin.pers', 'w'), serialize($bbb));

$ccc = Array(
'login' => 'admin',
'password' => md5('derparol'),
'style' => 'blue.css',
'rules' => '2'
);
fwrite(fopen('./customize/subadmin.pers', 'w'), serialize($ccc));

Скриптик один раз отрабатывает и у нас в папке admin появляется файл admin.list и директория cusomize, в которой будут храниться персональные данные. Последнюю желательно защитить соответствующим .htaccess

Deny from all

2. В default.php появляется форма:

/**
* Form for LOG-IN
* Форма входа
*/


if(!defined('ADMIN'))
{
?>
<FORM name="authorization" action="./" method="POST">
<
TABLE>
<
TR>
<
TD>Login</TD>
<
TD><INPUT type="text" name="login" size="20"></INPUT></TD>
</
TR>
<
TR>
<
TD>Password</TD>
<
TD><INPUT type="password" name="password" size="20"></INPUT></TD>
</
TR>
<
TR>
<
TD colspan="2" align="center"><INPUT type="submit" value="LOG-IN"></INPUT></TD>
</
TR>
</
TABLE>
</
FORM>
<?php
}


3. Ну и самое главное в основном index.php:

/**
* Checking login--password
* Проверка логина и пароля
*/


if( !empty($_POST['login']) && !empty($_POST['password']) )
{
$login = $_POST['login'];
$password = $_POST['password'];
$admins = unserialize(file_get_contents('./admin/admin.list'));
if(array_key_exists($login, $admins))
{
if(is_file('./admin/customize/'.$login.'.pers'))
$customs = unserialize(file_get_contents('./admin/customize/'.$login.'.pers'));
if($customs['password'] == md5($password))
{
echo
'<br>Получена пара <B>'.$login.' - '.$password.'</B>
<br>Вы являетесь администратором с уровнем доступа: <B>'
.$customs['rules'].'</B>
<br>Выбранный стиль: <B>'
.$customs['style'].'</B>';
define('ADMIN', $customs['rules']);
}
else die('Incorrect password!');
}
else die('Incorrect login!');
}
else die('Login or password is blank');

Пробуем вводить admin-parol и subadmin-derparol. Смотрим.
После этого по идее суем в сессию идентификатор админа и редиректим на ./admin, например. Тут уж, twin, сам решай, как лучше.

P.S. Мне одному кажется, что я любитель все усложнять? rolleyes.gif
У меня ощущение, что я слишком громоздко все делаю huh.gif

Спустя 43 минуты, 41 секунда (22.11.2009 - 23:27) twin написал(а):
Krevedko
Цитата
я кстати понял, что мы наверное сайт-галерею делаем



Да не факт... Это просто первое что пришло в голову)))

Shturman
Знач так. Во первых очень режет глаз это:
fwrite(fopen('./admin.list', 'w'), serialize($aaa));

Файлы не только не блокируются, но и не закрываются даже. И еще используется 'w'
Конечно, скрипт одноразовый, но нужно делать все как положено. Расслабляться не надо. Вот функция, я её специально сейчас написал.
/**
* Function of record of files
* Функция записи файлов
*/

function put_contents($filename, $content)
{


if(function_exists('file_put_contents'))
return file_put_contents($filename, $content);

if(!file_exists($filename))
fclose(fopen($filename, "a+t"));

$f = fopen($filename, "r+t");

while(!flock($f, LOCK_EX + LOCK_NB))
sleep(1);

ftruncate($f, 0);
fseek($f, 0, SEEK_SET);
fwrite($f, $content);

return fclose($f);
}



Не проверял. Проверьте кто нибудь под 4-кой, будет работать?
И кто сможет расписать алгоритм? Если трудно - я сам распишу.
Давайте будем писать чисто, без всяких авось. К тому же это совсем не трудно.

Во вторых.
Цитата
2. В default.php появляется форма:

Ни в коем случае. Весь HTML "появляется" только в шаблонах/
Никогда в PHP.
Кстати сразу.
Цитата
А почему файлы имеют ресширение tpl (темплейт)..это ж вроде в смарти применяется. Почему не html ?

а вот именно для того. что бы разграничить. HTML файлы все таки самодостаточны должны быть.C доктайпом, заголовками и телом. А темплэйт
это часть html страницы. Ну а смарти... хоть что то полезное то можно взять из этого монстра? Если там все остальное - чё попало))

Цитата
3. Ну и самое главное в основном index.php:

Давай наверно все таки вынесем это в отдельный файл. А то слишком некрасиво будет. Ты и сам заметил
Цитата
У меня ощущение, что я слишком громоздко все делаю

Спустя 18 минут, 22 секунды (22.11.2009 - 23:45) Krevedko написал(а):
кстати вот попробовал такую форму ввода пароля сделать

if (!isset($_SERVER['PHP_AUTH_USER']))
{
header("WWW-Authenticate: Basic realm=\"My Realm\"");
header("HTTP/1.0 401 Unauthorized");
echo "Доступ разрешен только при вводе логина и пароля\n";
exit;
}
else
{
echo 'логин ' . $_SERVER['PHP_AUTH_USER'];
echo 'пароль ' . $_SERVER['$PHP_AUTH_PW'];
}


логин выводит, а пароль нет. просто пишет пароль и все...
почему ? unsure.gif

Спустя 7 часов, 2 минуты, 7 секунд (23.11.2009 - 06:48) Argnist написал(а):
Штурман, кто же пишет теги заглавными буквами? И зачем нам какие-то глобальные константы, если есть сессии? И зачем 2 файла, если можно совместить все в один с разными rule ?

Спустя 1 минута, 55 секунд (23.11.2009 - 06:50) Shturman написал(а):
Вот чего не понял:

ftruncate($f, 0); // Урезание файла (а зачем, собсно?)
fseek($f, 0, SEEK_SET); // Перемещаемся на нулевой символ (тоже зачем?)

Спустя 4 минуты, 43 секунды (23.11.2009 - 06:54) Shturman написал(а):
Цитата
Штурман, кто же пишет теги заглавными буквами?

Где? huh.gif Аааа, HTML? - я так пишу, мне так удобнее.
Цитата
И зачем нам какие-то глобальные константы, если есть сессии?

Я ж написал "После этого по идее суем в сессию идентификатор админа и редиректим на ./admin, например. Тут уж, twin, сам решай, как лучше."
Цитата
И зачем 2 файла, если можно совместить все в один с разными rule ?

Если ты про admin.list и файлы с настройками, то поясню. Смысл тот, что иногда надо заблокировать админа, но не удалять его настроек на случай возвращения прав. Тут мы можем просто удажить его имя из списка и все, а если понадобится - вернуть. Да и удобнее, мне кажется, хранить все по полочкам.

Спустя 1 минута, 41 секунда (23.11.2009 - 06:56) Argnist написал(а):
Я не понял ЗАЧЕМ что-то проверять на PHP 4? Если ЭТО стоит на хостинге, этот хостинг можно выкинуть на помойку. Все нужно делать на PHP5 имхо. И вместо этой громадины простое file_put_contents($filename, $data);

Спустя 3 минуты, 49 секунд (23.11.2009 - 07:00) Argnist написал(а):
Цитата

Где?  huh.gif  Аааа, HTML? - я так пишу, мне так удобнее.

У нас в темплайте страницы задан доктайп, ему нужно следовать.

Цитата

Я ж написал "После этого по идее суем в сессию идентификатор админа и редиректим на ./admin, например. Тут уж, twin, сам решай, как лучше."

Тогда константу надо выкинуть

Цитата

Если ты про admin.list  и файлы с настройками, то поясню. Смысл тот, что иногда надо заблокировать админа, но не удалять его настроек на случай возвращения прав. Тут мы можем просто удажить его имя из списка и все, а если понадобится - вернуть. Да и удобнее, мне кажется, хранить все по полочкам.

Делаем ему rule=0 и нет проблем. Хранить в куче файлов не удобно. А если появится rule=3,4,5,6,7 будет 7 файлов?))

Спустя 13 минут, 47 секунд (23.11.2009 - 07:14) Shturman написал(а):
Цитата (Argnist @ 23.11.2009 - 04:00)
А если появится rule=3,4,5,6,7 будет 7 файлов?))

А вот это ты с чего взял-то? Уровень доступа никак не завязан с количеством файлов. admin и subadmin это логины. Пусть будут Петя с Васей, если так понятнее )))

В принципе, у нас в admin.list идет login => 0, можно уровень доступа сюда засунуть, а в папке каждому админу соответствует ОДИН файл со всеми его настройками, которых в зависимости от проекта может стать много.

Спустя 6 минут, 53 секунды (23.11.2009 - 07:20) Argnist написал(а):
Ну и зачем это надо?) если появится 3,4,5,6 админ, то перебирать кучу файлов, если всегда можно все запихать в один.

Спустя 19 минут, 57 секунд (23.11.2009 - 07:40) twin написал(а):
Цитата
Вот чего не понял:

        ftruncate($f, 0);                                   // Урезание файла (а зачем, собсно?)
        fseek($f, 0, SEEK_SET);                      // Перемещаемся на нулевой символ (тоже зачем?)

Урезание файла до нулевой длинны - это очистка)))
А на нулевой уровень - это в начало файла. Вообще это эмуляция режима "w" так как сам по себе этот режим достаточно непредсказуем и часто рушит файлы.
Цитата
Я не понял ЗАЧЕМ что-то проверять на PHP 4?
Всё моё нутро призывает согласиться с этим. Но факт есть факт До сих пор попадаются хостинги с 3!!! версией PHP ну а четверок еще вполне достаточно. Буквально на прошлой неделе переписывал скрипт под четверку, потому что у заказчика оплачен такой хостинг.
Хотя конечно - циклиться мы на этом не будем. Но если есть такая возможность, то почему бы и нет... Ведь если есть file_put_contents() функция дальше исполняться не будет.
Цитата

Цитата
Где?    Аааа, HTML? - я так пишу, мне так удобнее.

У нас в темплайте страницы задан доктайп, ему нужно следовать.

Поддерживаю. Писать надо валидно.

Спустя 4 минуты, 4 секунды (23.11.2009 - 07:44) Shturman написал(а):
Цитата

А на нулевой уровень - это в начало файла. Вообще это эмуляция режима "w" так как сам по себе этот режим достаточно непредсказуем и часто рушит файлы.

А, так вот, почему тебе 'w' не понравилось...

Цитата

Поддерживаю. Писать надо валидно.


Хорошо, убедили.

twin, скажи, ты видишь будущее у такой концепции хранения данных, как я предлагаю? Или как-то по-другому видишь?

Спустя 11 минут, 58 секунд (23.11.2009 - 07:56) Argnist написал(а):
Посоветуй заказчику написать письмо админам, чтобы обновили пыху. Сам так просил перейти с пхп4 на пхп5, сделали за сутки.

А так
Цитата
Но если есть такая возможность, то почему бы и нет... Ведь если есть file_put_contents() функция дальше исполняться не будет
код обрастет ненужной шелухой.

Кстати можно вопрос? Почему здесь выбрана процедурная парадигма, а не ООП?

Спустя 15 минут, 39 секунд (23.11.2009 - 08:12) twin написал(а):
Цитата
twin, скажи, ты видишь будущее у такой концепции хранения данных, как я предлагаю? Или как-то по-другому видишь?

Немного не так, хотя идея хорошая. Сейчас обосную.
Дело в том, что это самая интимная настройка сайта. Доступ к этой настройке может быть только у ооочень ограниченного круга людей. Владелец сайта, его жена и любовница к примеру.
По этому выносить эту настройку в админку нельзя. С другой стороны мы должны предоставить возможность изменять её как можно проще. А идея с разделением инфы по файлам тут на мой взгляд вполне логична. Не так много бывает этих самых админов и не так часто шарятся они по админке. Но зато абсолютно не разбирающийся в технологиях человек (хозяин сайта) сможет в специальном каталоге выбрать файл "ivanov.txt" и удалить(уволить) его.
Другой вопрос в том, как это организовано при логине. Я бы сначала попытался найти файл с таким именем, и потом, если он найден, прочитал бы его и сравнил пароль.

Вот тут опять дилема. Запись в файле можно организовать просто, без сериализации.
Цитата
Имя: Иван Петрович
Пароль: Ракета
Уровень доступа: 3

Тогда можно будет вносить изменения простым блокнотом. И любой, совершенно далекий от программирования человек (хозяин сайта) сможет не напрягаясь изменить уровень доступа к примеру.
Но тут очень некрасиво с точки зрения безопасности.
1. Пароль в явном виде
2. Файл нужно будет читать, а не подключать. А это означает, что появится лазейка к этим файлам.

Так что есть повод для размышления.

Спустя 3 минуты, 39 секунд (23.11.2009 - 08:16) twin написал(а):
Цитата
код обрастет ненужной шелухой.

ну может и так... Подумаем.

Цитата
Кстати можно вопрос? Почему здесь выбрана процедурная парадигма, а не ООП?

Потому что вот.

Спустя 40 минут, 44 секунды (23.11.2009 - 08:56) Ka4_0k написал(а):
Цитата
Но тут очень некрасиво с точки зрения безопасности.
1. Пароль в явном виде
2. Файл нужно будет читать, а не подключать. А это означает, что появится лазейка к этим файлам.

Так что есть повод для размышления.

А может сделать отдельный уровень и для заказчика? А данные хранить с помощью блоуфиш например. Ну и тоже добавлять в нужные места несколько рандомных символов, а потом при расшифровке их оттуда доставать. Так у заказчика будет удобный интерфейс управления одминами. И файлы будут тоже защищены.

Спустя 14 минут, 40 секунд (23.11.2009 - 09:11) twin написал(а):
Немного по подробнее плиз, не совсем понятен алгоритм.

Я вообще склоняюсь к тому, что интерфейса у этой настройки быть не должно. Нет человека, как говорится - нет проблемы. Люди все взрослые и уж блокнотом то заказчик наверняка пользоваться умеет. А на счет блоуфиш... нет смысла шифровать никакие данные кроме пароля. А пороль все же лучше не шифровать, а хэшировать. И хотя блоуфиш довольно криптостойкий алгоритм, зачем искушать судьбу, там где можно этого не делать...

Спустя 5 минут, 48 секунд (23.11.2009 - 09:17) Ka4_0k написал(а):
Ну например: зашифровать с помощью блоуфиш, через каждые 2 символа вставлять рандомный, потом ещё раз зашифровать и записать. Админка ведь такая вещь, где не будет больше 300 просмотров в день, а значит нужно больше волноваться за безопасность, а не за скорость. Таким образом будет возможность у заказчика просто изменять уровень доступа и данные админов в "юзер френдли" интерфейсе.
З.Ы, Например удобнее ведь настраивать через визуальный интерфейс, чем через конфиги smile.gif
Я конечно чувствую что сейчас обсыпят, но это моё предложение:)

Спустя 18 минут, 46 секунд (23.11.2009 - 09:36) twin написал(а):
Ну вообще то куда первым делом пытется получить доступ хакер? Разумеется в админку. То есть именно в интерфейс. А тут получится два интерфейса. Один для настройки доступов и второй уже непосредственно сам. А значит автоматически расширяется поле для попыток взлома. А нет интерфейса - нет самого предмета. И взлом невозможен по определению. С этой стороны по крайней мере.

Ты прав, в админку ходят редко. А права доступа меняются еще реже. А может и совсем не меняются, если это личный сайт.
FTP доступ у хозяина есть всяко разно, не стоит тут мудрить с интерфейсом ИМХО. Нужно только компромисс найти, как захэшировать пароль.

В принципе можно сделать в админке скрипт, который будет это делать. И тогда соискатель может сам захэшировать пароль и предоставить главному админу хэш. Но как то не красиво это и путанно...

Спустя 13 минут, 31 секунда (23.11.2009 - 09:49) Ka4_0k написал(а):
Ну вот всё равно надо делать хоть часть этого в админке. Можно ведь сделать чтобы в строке адреса при передаче определенного значения только запускался этот интерфейс. Ну тоесть сделать какуюто сроку, например хеш чего то и при передаче этой сроки в качестве параметра будет доступна эта возможность. Так будет максимально усложнен доступ туда для хакера:) ведь поди догадайся что надо передать строку и какую ее передавать.

Спустя 34 минуты, 50 секунд (23.11.2009 - 10:24) Shturman написал(а):
А еще знаете, как делается?
Создается файлик типа passwords, ну или еща как-то пафосно, а в нем штук 300 пар логинов и рандомных хэшей. Пущай, родимый, равлекается!
А реальный файл с паролями называется, например, banner_top и естесственно, без интерфейса. Просто заказчику объяснить, что это сувенир для хакеров и все. smile.gif

twin, я тут натыкался, что при переходе в какой-либо интерфейс пользователя идет переход на https. Для меня это пока темный лес, но может, тебе покажется применимым?

Спустя 28 минут, 34 секунды (23.11.2009 - 10:53) twin написал(а):
HTTPS штука очень хорошая. Но это использует шифрованный протокол SSL (или TLS), сертификат для которого стоит денек. То есть заказчику головная боль. Нам не годится.
Прятать файлы под другими именами, а так же подсовывать липовые данные тоже не очень удачная идея Нужно стараться делать так, что бы не провоцировать злыдней, а сразу дать понять - нечего тут делать.

Спустя 29 минут, 47 секунд (23.11.2009 - 11:22) twin написал(а):
Компромисс может быть следующим: инвайт.
То есть регистрация с разрешением. Владелец сайта выдает инвайт тому, кого хочет ввести в группу администраторов. Инвайтом может быть рандомное имя файла, в который соискатель уже через интерфейс пропишет свои данные. В нем уже сразу будет установлен доступ.
При сохранении скрипт переимменует файл. Автоматически доступа из админки к этому файлу больше не будет. Изменить что то владелец сможет уже только по FTP протоколу.
Кто попробует реализовать?
Алгоритм.
1. Создаем файл-инвайт с рандомным именем и уровнем доступа. Допустим это просто пустой текстовый файл с единственной цифрой внутри.
2. Имя файла будет служить своеобразным паролем, который соискатель будет должен ввести в поле при регистрации.
3. После регистрации в файл прописывается имя, хэш пароля и уровень доступа, который там уже есть.
4. После того, как форма заполнена, файл переименовывается (и наверно перемещается). Соответственно доступ к нему закрывается.

Спустя 44 минуты, 43 секунды (23.11.2009 - 12:07) Shturman написал(а):
Цитата (twin @ 23.11.2009 - 08:47)
Вот этот главный админ, который устанавливал сайт, раздает инвайты.

Еще вопрос: инвайт выдается уже зарегистрированному пользователю? Т.е. мы при каждом входе любого пользователя должны проверять, не дожидается ли его инвайт, так? Не есть ли это уязвимость?

Спустя 6 минут, 42 секунды (23.11.2009 - 12:14) Argnist написал(а):
Ну получит хакер базу с шифрованными паролями и что дальше? И вообще чем ему сложнее получить всю базу, чем 1 файл? Если где-то будет серьезная уязвимость, он может точно так же все файлы скачать.

Спустя 11 минут, 3 секунды (23.11.2009 - 12:25) twin написал(а):
Цитата
Еще вопрос: инвайт выдается уже зарегистрированному пользователю? Т.е. мы при каждом входе любого пользователя должны проверять, не дожидается ли его инвайт, так? Не есть ли это уязвимость?

Нет, инвайт выдается только тем, кого владелец решил произвести в чин администратора. Ничего проверять не надо. Сами разберутся меж собой.

Argnist
Цитата
Ну получит хакер базу с шифрованными паролями и что дальше? И вообще чем ему сложнее получить всю базу, чем 1 файл? Если где-то будет серьезная уязвимость, он может точно так же все файлы скачать.

Вот получит он базу, а какой то из админов по безолаберности своей выбрал себе такой пароль 1234567.
Как ты считаешь, сколько минут потребуется мне, чтобы написать скрипт и отбрутить этот хэш? И тут же попасть в админку.
А к файлам попасть намного сложнее. Это шелл надо как то засунуть. И при аккуратных действиях главного админа он может спать спокойно, не волнуясь за сайт. (Ну или почти спокойно) smile.gif

Спустя 13 минут, 20 секунд (23.11.2009 - 12:38) twin написал(а):
Argnist
Цитата
Мне кажется все равно это паранойя %) брутил как-то пароль к рару, на 4х символах мне надоело ждать)

В сети полно ресурсов, которые брутят пароли и словари используют. До 7-ми символов спокойно брутится, если пароль написан безолаберно.
А паранойя тут очень даже уместна. Мы же несем ответственность за чужую собственность. Защиты много не бывает.
Shturman
Цитата
Тогда как юзер узнает о том, что для него есть инвайт и нужно зайти в админку, чтобы его активировать?

По аське спишутся. Или мож они вообще в одном офисе. Это детали уже))

Спустя 3 часа, 3 минуты, 4 секунды (23.11.2009 - 15:41) Shturman написал(а):
twin, опять ругаться будешь, но я опять издалеа начал biggrin.gif
Выложу скрипты, расписывать пока сил нет больше. Завтра продолжу...
В папке /skins/tpl появился файл ajax-form.tpl

<script type="text/javascript" src="<?php echo 'http://'.$_SERVER['HTTP_HOST'].'/skins/js/ajax-form.js' ?>" />
<
form name="auth" method="POST">
<
table>
<
tr>
<
td>
Login
</td>
<
td>
<
input type="text" name="login" />
</
td>
</
tr>
<
tr>
<
td>
Password
</td>
<
td>
<
input type="password" name="password" />
</
td>
</
tr>
<
tr>
<
td align="center" colspan="2">
<
input type="button" value="LOG-IN" OnClick='send()' />
</
td>
</
tr>
</
table>
</
form>
<
div id="monitor"></div>

В папке /skins/js появился файл ajax-form.js


/**
* Function creates XMLHttp object
* Функия, содзающая объект XMLHttp
*/

var req = Create();
function Create()
{
if(navigator.appName == "Microsoft Internet Explorer")
{
req = new ActiveXObject("Microsoft.XMLHTTP");
}
else
{
req = new XMLHttpRequest();
}

return req;
}

/**
* Funtion for encodung array to URIComponent
* Функция, перекодирующая массив данных в URIComponent
*/


function urlEncodeData(data)
{
var query = [];
if (data instanceof Object)
{
for (var k in data)
query.push(encodeURIComponent(k) + "=" + encodeURIComponent(data[k]));
return query.join('&');
}
else
return
encodeURIComponent(data);
}

/**
* Main AJAX function
* Главная функция AJAX
*/


function Request(query)
{
req.open('POST', 'http://localhost/libs/ajax.php' , true );
req.onreadystatechange = Refresh;
req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf8");
req.send(query);
}

/**
* Main action function
* Основная рабочая функция
*/


function Refresh()
{
var ready = req.readyState;
var answer = req.responseText;
text = "Please wait...";
if( ready == 4 )
text = answer;
document.getElementById("monitor").innerHTML = text;
}

/**
* Function for send datas from templete form
* Функция для отправки данных из шаблонной формы
*/


function send()
{
document.getElementById("monitor").innerHTML = '';
if(document.forms['auth'].login.value != '' && document.forms['auth'].password.value != '')
{
var datas = [];
datas['login'] = document.forms['auth'].login.value;
datas['password'] = document.forms['auth'].password.value;
Request(urlEncodeData(datas));
}
else
document.getElementById("monitor").innerHTML = '<font color="red">Пожалуйста, заполните все поля.</font>';
}

В иднексе дописано

/**
* We connect the template of form
* Подключаем шаблон формы
*/


include './skins/tpl/ajax-form.tpl';

ну и в /libs появился файлик с одной-единственной строчкой ))

Пробуем!
некоторое время хост вырубать не буду.

Спустя 41 минута, 41 секунда (23.11.2009 - 16:23) tata написал(а):
Shturman, пробую)). На пустые поля просит заполнить в красном цвете, а на заполненные :
"Начинаю рыться в архивах и искать такого юзверя. Ждите... ;-)"
А скока ждать-то?))))

Спустя 1 час, 26 минут, 44 секунды (23.11.2009 - 17:50) Shturman написал(а):
Ну написано же "Ждите..." biggrin.gif
Сервачок у меня медленный wink.gif

ajax.php создан, но в нем пока лишь строка

echo "Начинаю рыться в архивах и искать такого юзверя. Ждите... ;-)";

Собсно, это пока только механизм формы, который не конфликтует с реврайтом и не показывает юзеру, куда данные ушли. Юзер вообще не увидит какого-либо перехода, ибо в monitor можно выводитть что угодно. Причем, можно даже саму форму в этот div засунуть и при верной паре логин-пароль заменять форму на необходимый контент. Вариантов много.
Это лишь инструментарий пока.

localhost, вроде, поправил уже. Может, не везде... Не могу вспомнить, как в javascript-е выглядит аналог $_SERVER['HTTP_HOST'], поэтому, пока ручками IP пописан.

Спустя 2 часа, 52 минуты, 28 секунд (23.11.2009 - 20:42) twin написал(а):
Argnist
Цитата
Я бы лучше jquery использовал, чем сырой ajax)

У нас круче есть. Ничего лишнего и работает как часики.

Спустя 17 часов, 15 минут, 10 секунд (24.11.2009 - 13:57) Хозяин Огня написал(а):
include dirname(dirname(__FILE__)) .'/config.php';


А почему нельзя написать include "../config.php"; ?

Спустя 36 минут, 6 секунд (24.11.2009 - 14:33) twin написал(а):
Можно... Просто как то принято не топать вверх, это считается не камильфо. Если есть возможность указать прямой и логичный путь от корня системы, стоит это сделать.

Спустя 4 часа, 37 минут, 5 секунд (24.11.2009 - 19:10) live Uucyc написал(а):
Цитата
include dirname(dirname(__FILE__)) .'/config.php';

почему дважды используется dirname, что это дает??

Спустя 15 минут, 35 секунд (24.11.2009 - 19:26) Хозяин Огня написал(а):
Ну как бы внутренний дирнейм определяет нашу текущую папку - "админ", второй - папку, в которой находится папка "админ".

Спустя 9 минут, 27 секунд (24.11.2009 - 19:35) VolCh написал(а):
Цитата (twin @ 24.11.2009 - 15:33)
Можно... Просто как то принято не топать вверх, это считается не камильфо. Если есть возможность указать прямой и логичный путь от корня системы, стоит это сделать.

По-моему это принято как раз, чтобы избежать проблем с сепараторами в разных осях, то есть имеет смысл писать или
include "../config.php";

или
include dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR .'config.php';

Во втором случае мы гарантированно получаем полное имя файла, независимо от ОС и ФС.

Спустя 15 минут, 50 секунд (24.11.2009 - 19:51) twin написал(а):
live Uucyc
Цитата
почему дважды используется dirname, что это дает??

Когда возникают такие вопросы, просто делай так:
echo dirname(dirname(__FILE__)) .'/config.php';

VolCh
Цитата
По-моему это принято как раз, чтобы избежать проблем с сепараторами в разных осях

Вообще PHP не чуствителен к сепараторам. Была раньше проблема, сейчас это специально реализовано, зачем лишние движения?

Спустя 38 минут, 34 секунды (24.11.2009 - 20:30) VolCh написал(а):
Цитата (twin @ 24.11.2009 - 20:51)
Вообще PHP не чуствителен к сепараторам. Была раньше проблема, сейчас это специально реализовано, зачем лишние движения?

twin

- не факт, что в одном из релизов этот баг опять не всплывёт где-нить

- PHP может быть собран не только под nix/win, а под какой-нить там CiscoOS разделитель может быть # например

- Если допустить, что 1 и 2 мы избежали, тогда, по-моему, нет и смысла городить dirname() - если система не понимает "../config.php", то, скорее всего, она не понимает и "/config.php", а если понимает, то зачем делать лишние движения и создавать лишнюю нагрузку (два системных вызова плюс просчёт пути против одного просчёта пути - копейки, конечно, но копейка рубль бережет smile.gif ), если 100% кроссплатформенности все равно не получим? Работает под nix/win и ладно smile.gif

Спустя 11 минут, 50 секунд (24.11.2009 - 20:42) glock18 написал(а):
1. кто решил, что dirname == '../', марш в мануал.
2. twin, dirname вовсе является
Цитата
прямой и логичный путь от корня системы

на деле он похож на ../, хотя и не является таковым. Путь от корня - это путь от корня, а не от __FILE__ в любом случае.

Спустя 17 минут, 39 секунд (24.11.2009 - 20:59) twin написал(а):
VolCh
Мне самому это не нравится, а многим не нравится ../
Но городить какой то такой огород
include preg_replace("#[\\/]+#", DIRECTORY_SEPARATOR, dirname(dirname(__FILE__))) . DIRECTORY_SEPARATOR .'config.php';
просто рука не поднимается... Все таки не зря же эту фичу реализовали в php, почему бы и нет... Оси осями, а пых то сам разберется.
Хотя на самом деле убедительно. Надо порыться... Может и правда наплевать на условности.

glock18
Цитата
Путь от корня - это путь от корня, а не от __FILE__ в любом случае.
Не допонял я что то... До директории, в которой файл, но ведь от корня файловой системы...

Спустя 4 минуты, 57 секунд (24.11.2009 - 21:04) VolCh написал(а):
Цитата (glock18 @ 24.11.2009 - 21:42)
1. кто решил, что dirname == '../', марш в мануал.

А кто решил? dirname(__FILE__) практически (под *nix и win) равна realpath("./") smile.gif

Хотя в любом случае имя файла распарсится на полное на уровне ОС и открывать она будет его по полному пути.

Спустя 1 минута, 16 секунд (24.11.2009 - 21:06) glock18 написал(а):
я к тому, что если уровень вложенности файла поменяется, то придется в любом случае менять количество ../ или dirname(). потому что путь строится от этого файла, а не от корня хоста.

Спустя 7 минут, 28 секунд (24.11.2009 - 21:13) VolCh написал(а):
Цитата (twin @ 24.11.2009 - 21:59)
Мне самому это не нравится, а многим не нравится ../
Но городить какой то такой огород
include preg_replace("#[\\/]+#", DIRECTORY_SEPARATOR, dirname(dirname(__FILE__))) . DIRECTORY_SEPARATOR .'config.php';
просто рука не поднимается... Все таки не зря же эту фичу реализовали в php, почему бы и нет... Оси осями, а пых то сам разберется.
Хотя на самом деле убедительно. Надо порыться... Может и правда наплевать на условности.

А зачем такой-то городить? blink.gif
В начале где-нибудь сделать
define("DS", DIRECTORY_SEPARATOR);
- только для краткости (с) smile.gif

А потом использовать везде
include dirname(dirname(__FILE__))) . DS . 'config.php';


Зачем нам менять слэши, если dirname (а еще раньше __FILE__) вернула нам путь именно в том виде, который 100% понимает та ось, где крутится скрипт? Причём как раз используя символ DIRECTORY_SEPARATOR в качестве разделителя



Спустя 5 минут, 42 секунды (24.11.2009 - 21:19) VolCh написал(а):
Цитата (glock18 @ 24.11.2009 - 22:06)
я к тому, что если уровень вложенности файла поменяется, то придется в любом случае менять количество ../ или dirname(). потому что путь строится от этого файла, а не от корня хоста.

Ну это-то само собой, что так, что этак придётся менять, раз уж решили админку через отдельный роутер обрабатывать, а сайт должен иметь возможность устанавливаться в произвольную папку. Ну, как вариант, сделать симлинк из админки на главный конфиг smile.gif но это только под никсами вроде работать будет

Спустя 47 минут, 51 секунда (24.11.2009 - 22:07) twin написал(а):
Да ну их. Поменяем на нормальную штучку ../ и все. Чего на самом деле оглядываться. Раз это придумано, значит имеет право на жизнь.

Спустя 2 часа, 14 минут, 57 секунд (25.11.2009 - 00:22) twin написал(а):
VolCh
Цитата
Зачем нам менять слэши, если dirname (а еще раньше __FILE__) вернула нам путь именно в том виде, который 100% понимает та ось, где крутится скрипт? Причём как раз используя символ DIRECTORY_SEPARATOR в качестве разделителя
Вообще на сколько мне известно, сепаратор из константы подтормаживает процесс. Плюс конкатенация. Ну а так как большинство серваков все же не пользуют винду, ориентироваться лучше на массовость. Писать везде константу довольно муторно и неэкономично. Не думаю, что PHP не справится с этим под виндой Даже не думаю, что будет выигрыш по времени, если на неё ориентироваться. Зато под никсом будет полный ажур.

Хозяин Огня
Цитата
Зато получили представление об ещё одной функции и одной предопределённой константе))
так для того и. smile.gif

Спустя 13 часов, 29 минут, 12 секунд (25.11.2009 - 13:51) Shturman написал(а):
Инвайты (попытка реализовать)
Итак, в шаблонах появляется файл invite.tpl, подключаемый только если пользователь вошел в систему и существует либо константа ADMIN либо USER
invite.tpl

<table>
<tr>
<td><?php
echo defined('ADMIN')?'Ваш логин':'Логин доверившего' ?></td>
<td><input
type="text" size="25" name="adminname" /></td>
</tr>
<tr>
<td><?php
echo defined('ADMIN')?'Логин доверенного':'Ваш логин' ?></td>
<td><input
type="text" size="25" name="username" /></td>
</tr>
<tr>
<td>
Ваш пароль</td>
<td><input
type="password" size="25" name="password"/></td>
</tr>
<tr>
<td><?php
echo defined('ADMIN')?'Уровень прав':'Код активации' ?></td>
<td><input
type="password" size="25" name="invite"/></td>
</tr>
</table>


Еще один файл (я так думаю, модулем в админку)
invite.php

<?php

/**
* Function of record of files
* Функция записи файлов
*/

function put_contents($filename, $content)
{


if(function_exists('file_put_contents'))
return file_put_contents($filename, $content);

if(!file_exists($filename))
fclose(fopen($filename, "a+t"));

$f = fopen($filename, "r+t");

while(!flock($f, LOCK_EX + LOCK_NB))
sleep(1);

ftruncate($f, 0);
fseek($f, 0, SEEK_SET);
fwrite($f, $content);

return fclose($f);
}

/**
* Create file-invite
* Создаем файл-инвайт
*/


//Если пользователь авторизован, как админ, то содзана константа ADMIN
if(defined('ADMIN'))
{
//Проверка данных формы
if( !empty($_POST['username']) &&
!
empty($_POST['invite']) &&
!
empty($_POST['adminname'] &&
!
empty($_POST['password']) )
{
$code = substr(md5(rand(1, 100)), 5, 12);
$data = array(
'from' => $_POST['adminname'],
'to' => $_POST['username'],
'rules' => $_POST['invite'],
'code' => $code;
)


$path = ''.$_POST['username'];
// Помещаем данные в файл и выдаем админу код для активации инвайта юзером
put_contents($path, serialize($data));
?>
<B style="color: red; size: 14pt;"><?php echo $code ?> </B>
<?php

}
}

// Если пользователь авторизован как обычный юзер, то создана константа USER
elseif(defined('USER'))
{
// Проверка данных формы
if( !empty($_POST['adminname']&&
!
empty($_POST['username']) &&
!
empty($_POST['password']) &&
!
empty($_POST['invite']) )
{
$path = ''.$_POST['username'];
if(file_exists($path))
{
// Получение данных из файла
$data = file_get_contents($url);
// Сравнение
if( $data['from'] == $_POST['adminname'] &&
$data['to'] == $_POST['username'] &&
$data['code'] == $_POST['invite'] )
if(ChangeRules($data['rules'])) // Вызов функции, меняющей права пользователю, должна вернуть TRUE.
unlink($path); // Удаление использованного инвайта
}
else
echo 'Извините, насчет Вас распоряжений не было.';
}
}

?>

Тут я воспользовался функцией twin'а для создания файла put_contents(). Ее бы куда-нить вынести, много где пригодиться может.

ChangeRules() допишем, когда решим, в каком виде наши юзеры обитать будут. Туда же пойдет и изменение содержания списков админов.

P.S. Весь код из головы - не пробовал в действии... звиняйте уж cool.gif

Спустя 1 минута, 39 секунд (25.11.2009 - 13:52) Shturman написал(а):
Блин, в шаблоне, естесственно еще submit забыл biggrin.gif

А забыл потому, что так и не решил, как она будет работать - по сабмиту или через Ajax.

Ну и $path пока тоже абстрактный. Надо решить, где складывать инвайты.

-еще дополнение, когда определимся, как для нас выглядит вошедший юзер, добавим проврку логина и пароля и прикрутим проверку существования юзера, которому админ дает инвайт.

Спустя 1 час, 32 минуты, 53 секунды (25.11.2009 - 15:25) twin написал(а):
Ну вот, начало есть. Пока не торопись.
Я возьму за основу и в следующем уроке расскаже как работать с POST данными.

По коду три замечания:
1. Никакого вывода нельзя делать в скриптах. Я про это:
            ?>
<B style="color: red; size: 14pt;"><?php echo $code ?> </B>
<?php
Все что ты выводишь в скрипте - вылезет выше доктайпа. А это не дело.

2. Никакой логики не допустимо в шаблонах. Только переменные и вызов функций. И то из ограниченного списка. Я про это:
<td><?php echo defined('ADMIN')?'Ваш логин':'Логин доверившего' ?></td>


3. Константа defined('USER') у нас не определена нигде. По этому нужно было просто else. Зачем лишняя константа, если и так понятно, что если не админ, значит юзер.

Ну а с функцией put_contents() надо подумать еще.

Во первых договорились использовать "верблюжью" запись пользовательских функций, то есть первая часть маленькими буквами, потом большая, потом опять маленькие. Вот так:
putContents()

Во вторых, прозвучало мнение, что она излишня. Однако мы провели некоторый тест для file_put_contents() на ресурсе с очень большой ( до 200 уников в секунду) посещаемостью и выяснили, что не такая уж она и безопасная. Попробую написать для неё обертку, есть идея.
Это может и лишнее все, но хочется написать что то очень надежное и грамотное. smile.gif

Спустя 7 минут, 26 секунд (25.11.2009 - 15:33) Shturman написал(а):
Цитата (twin @ 25.11.2009 - 12:25)
Ну вот, начало есть. Пока не торопись...

Спасибо, что не обхаял сразу biggrin.gif

1. Про вывод до доктайпа - погорячился, да. Но я думал включать эту часть в виде модуля, т.е. после шапки.

2. Логика в шаблонах - эт что, два шаблона делать?

3. Константа defined('USER') - не определена пока. Но если просто else, то это не только зарегистрированный юзер, но и просто залетный. Я считал, что эту форму незарегистрированным вообще лучше не показывать.

давай, как решишь с функцией, так и обернем, а пока в коде просто поставим putContents и все.

P.S. А почему именно "верблюжья"? Откуда пошло?

Спустя 14 минут, 37 секунд (25.11.2009 - 15:47) twin написал(а):
Цитата
2. Логика в шаблонах - эт что, два шаблона делать?

Ну вообще в следующем уроке я вскользь прошелся по этому. Должен быть файл view.php который и будет приводить в порядок вывод. Это прокладка между контроллером и шаблонами.

По третьему пункту. А чем константа то поможет? Ты где хочешь её определять? Я что то этой логики недопонял. sad.gif

Цитата
А почему именно "верблюжья"? Откуда пошло?

Спустя 40 минут, 16 секунд (25.11.2009 - 16:28) Shturman написал(а):
Цитата (twin @ 25.11.2009 - 12:47)
По третьему пункту. А чем константа то поможет? Ты где хочешь её определять? Я что то этой логики недопонял. sad.gif

Ну вот смотри, ты заходишь на страницу, ну скажем Яндекса. Ты - рядовой пользователь и можешь пользоваться некоторыми продуктами без регистрации.
Например, банально, поиск.
Но вот тебе захтелось иметь почтовый ящик на Яндексе - ты регистрируешься. И таких, как ты n-ное количество. Над этим количеством m-ное количество админов, которым и раздает права Владелец.
Так вот до того момента, пока ты залогинился - ты рядовой юзер наравне с ботами Гугла, например, и прочими.
А когда ты вошел, ты либо зарегистрированный юзер, либо админ.

Вот для этого, я думаю, и надо различать консттанты USER и ADMIN, которые, кстати, могут нести информацию об уровне доступа wink.gif

Спустя 17 минут, 31 секунда (25.11.2009 - 16:45) twin написал(а):
У нас практически два сайта. Один для пользователей, другой для админов. Они пользуются общей библиотекой функций (моделями), но имеют собственные роутеры и контроллеры. По этому так их различать не надо вовсе. Скрипты юзера и админа ни где не пересекаются. Это более надежно.

А делать админку для админов - совсем огород получится. По этому на странице с входом нужно будет просто добавить поле - инвайт. И если инвайт есть, то выдавать его. Тогда соискатель сможет ввести его туда и получить форму регистрации.

Я такую логику имел ввиду. А доступы - это задел на будущее. Пока их будет два. Один для организации инвайтов - самый высокий. И второй - просто админ. А дальше будет видно.

Спустя 23 часа, 17 минут, 13 секунд (26.11.2009 - 16:02) Danusya написал(а):
Эх, растроилась я... huh.gif

Моего мозга блондинки после двух дней изучения PHP не хватило ни на что больше, кроме как буквально исполнить требования
Цитата
Нужно написать скрипт, который будет доставать из текстовых файлов в директории setup данные и помещать в свои теги. Title, description и так далее)).


т.е. в файл variables.php дописать
/** 
Определяем переменные для метатегов
*/

$keywords = file_get_contents ('./setup/keys.txt');
$title = file_get_contents ('./setup/title.txt');
$description = file_get_contents ('./setup/descr.txt');


Никаких сериализаций и прочих знаний, которые требуются для того, чтобы исполнить так, как нужно, у меня пока нет ph34r.gif
Ушла в гугл, вернусь нескоро...

Спустя 49 минут, 28 секунд (26.11.2009 - 16:52) Krevedko написал(а):
Ну вот смотри. Предположим ты в файл записываешь две новости.
Потом извлекаешь из файла. Как скрипт поймет, что вот закончилась первая новость, началась вторая...?

Можно писать каждую новую новость в новой строке. Тогда file_get_contents каждую строчку поместит в новый элемент массива. Можно разделять каждую новость каким-то символом, например |
Чтобы он знал, что вот первая закончилась, пошла вторая. Потом вытягиваем это месиво из файла и распарсиваем на куски...
Вот чтобы без этих танцев с бубном используют сериализацию.
Т.е. мы массив новостей упаковываем специальным образом (serialize)
ложим в файл.
Потом когда надо извлекаем и распаковываем (unserialize) и вуаля..все на своих местах.
Если я неправ где-то, то поправьте.

Спустя 2 часа, 46 минут, 53 секунды (26.11.2009 - 19:39) Danusya написал(а):
Итого у меня вышел код, почти как у Степана (на него ориентировалась)

Вынесла пока по отдельным файлам, чтобы самой не запутаться:

1. ./setup/serialize.php

<?php

$meta_array = array (
"news" => array (
"keywords" => "новинки",
"description" => "Что происходит в мире",
"title" => "Последние Новости",
),

"gallery" => array (
"keywords" => "Картинки",
"description" => "фото и видео",
"title" => "Наша галерея",
),
);


$act_serialize = serialize ($meta_array);

file_put_contents ('./meta.txt', $act_serialize);

print ("Done!");

?>


2. ./setup/meta.txt
В нем после запуска сериализации появилось воть такое:
a:2:{s:4:"news";a:3:{s:8:"keywords";s:14:"новинки";s:11:"description";s:39:"Что происходит в мире";s:5:"title";s:33:"Последние Новости";}s:7:"gallery";a:3:{s:8:"keywords";s:16:"Картинки";s:11:"description";s:22:"фото и видео";s:5:"title";s:23:"Наша галерея";}}


3. ./metagenerate.php

<?php

/**
Забираем сериализованные данные и разсериализовываем их
*/


$data_meta = file_get_contents ('./setup/meta.txt');
$act_unserialize = unserialize ($data_meta);

/**
Определяем переменные для метатегов
*/


$title = $act_unserialize [$GET['mod']] ['title'];
$description = $act_unserialize [$GET['mod']] ['description'];
$keywords = $act_unserialize [$GET['mod']] ['keywords'];

?>


4. В файле index.php заинклудила метагенератор

/**
Подключаем данные метатегов для страницы
*/

include './metagenerate.php';


Живьем все это добро лежит тут, например так или так, только на данный момент там не работает мод рерайт (из-за перенастройки сервера), через пару часов включу обратно.

Спустя 2 часа, 9 минут (26.11.2009 - 21:48) Danusya написал(а):
1. Ок, буду юзать гугл транслейт biggrin.gif

2. Даже нинаю, что и думать... У меня редактор kwrite (линуховый), там только пробелы и никаких табов, могу сделать скрины, те пробелы, которые не видны тут, там как на картинке, может разница шрифтов или еще что-нибудь...

3. Читаю, спасибо, как раз искала что-то подобное, очень кстати ))

4. Спасибо, ты вселил в меня надежду, буду стараться! rolleyes.gif

Спустя 1 день, 29 минут, 6 секунд (27.11.2009 - 22:17) Danusya написал(а):
Вставлю свое скромное ИМХО, для совсем новичков нужно было бы немного разжевать про сессии и куки, лично я сегодня весь день потратила на то, чтобы четко представить, как эти слоны работают =)

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

Спустя 2 дня, 14 часов, 22 минуты, 54 секунды (30.11.2009 - 12:40) Wollff написал(а):
Цитата (twin @ 25.11.2009 - 13:45)
У нас практически два сайта. Один для пользователей, другой для админов. Они пользуются общей библиотекой функций (моделями), но имеют собственные роутеры и контроллеры. По этому так их различать не надо вовсе. Скрипты юзера и админа ни где не пересекаются. Это более надежно.

А делать админку для админов - совсем огород получится. По этому на странице с входом нужно будет просто добавить поле - инвайт. И если инвайт есть, то выдавать его. Тогда соискатель сможет ввести его туда и получить форму регистрации.

Я такую логику имел ввиду. А доступы - это задел на будущее. Пока их будет два. Один для организации инвайтов - самый высокий. И второй - просто админ. А дальше будет видно.

twin, можно об этом подробнее? shturman, предлагает хорошую архитектуру:
1. залётные - посетители со всего интернета, которые свободно могут познакомиться с содержанием ресурса и в полной мере себя тут проинформировать.
2. пользователи - те, кто зарегистрировался и благодаря этому получил возможность пользоваться предлагаемыми ресурсом услугами.
3. администраторы - те, кто наполняет ресурс услугами.
4. владелец сайта
Если я верно понял, то 1-е регистрируются и становяться 2-ми. 2-е связываются с владельцем альтернативным методом (по телефону, ICQ...) и получают от него инвайт, переходят в категорию 3-х.

Спустя 2 минуты, 33 секунды (30.11.2009 - 12:42) Argnist написал(а):
я все не могу поверить, что реально держать пароли в БД чем-то опаснее, чем в файлах))

Цитата (twin @ 23.11.2009 - 16:25)
Цитата
Ну получит хакер базу с шифрованными паролями и что дальше? И вообще чем ему сложнее получить всю базу, чем 1 файл? Если где-то будет серьезная уязвимость, он может точно так же все файлы скачать.

Вот получит он базу, а какой то из админов по безолаберности своей выбрал себе такой пароль 1234567.
Как ты считаешь, сколько минут потребуется мне, чтобы написать скрипт и отбрутить этот хэш? И тут же попасть в админку.
А к файлам попасть намного сложнее. Это шелл надо как то засунуть. И при аккуратных действиях главного админа он может спать спокойно, не волнуясь за сайт. (Ну или почти спокойно) smile.gif

а что мешает в хеш ключей надобавлять?)


define(KEY, 'argni56s45t645s6a456ijfgwaheufh');
md5(KEY . (sha1(KEY . $pass)));

и тп?)

Спустя 3 минуты, 33 секунды (30.11.2009 - 12:46) Wollff написал(а):
мне кажется, что без интерфейса для владельца не обойтись. Не всё можно и удобно делать через ftp и полюбому он должен владеть полной картиной того, что происходит на его ресурсе.
В конце концов владелец - это тот, кто платит за всё деньги, и удобство пользования для него - явно приоритетная задача для разработчиков. Или?

Спустя 6 минут, 51 секунда (30.11.2009 - 12:53) glock18 написал(а):
Argnist
md5 имеет фиксированную длину. и узнать его достаточно просто. стоит злоумышленнику только увидеть его во второй части строки хэша, и все попытки запутать насмарку, потому что после этого выделить сам md5 будет достаточно просто.

Спустя 15 минут, 46 секунд (30.11.2009 - 13:08) Argnist написал(а):
Ты о чем? из какой второй части?)

Спустя 10 минут, 42 секунды (30.11.2009 - 13:19) glock18 написал(а):
а, вон чего. да, не заметил.

Спустя 1 час, 51 минута, 58 секунд (30.11.2009 - 15:11) twin написал(а):
Wolff
Цитата
shturman, предлагает хорошую архитектуру:

Именно её мы и пытаемся реализовать.
Argnist
Цитата
а что мешает в хеш ключей надобавлять?)

Да ни кто не мешает. Просто на данном этапе мы не работали с БД- во первых. Все таки достать пароль из базы проще (что с ним делать второй вопрос) - во вторых.
Wolff
Цитата
мне кажется, что без интерфейса для владельца не обойтись. Не всё можно и удобно делать через ftp и полюбому он должен владеть полной картиной того, что происходит на его ресурсе.
В конце концов владелец - это тот, кто платит за всё деньги, и удобство пользования для него - явно приоритетная задача для разработчиков. Или?

Лишний интерфейс - лишняя лазейка. Я уже писал. Наша первая задача - безопасность. Потому что если поломают один, второй, третий сайт на нашем движке, какая пойдет о нас слава? Вот и думаем как волков уцелеть и овец накормить.
К тому же мы делаем каркас, спартанский минимум. Подход к каждому заказчику индивидуален. Захочет интерфейс - слепим. Не захочет - все готово.

Спустя 1 час, 28 минут, 7 секунд (30.11.2009 - 16:39) Shturman написал(а):
Цитата (twin @ 30.11.2009 - 12:11)
Лишний интерфейс - лишняя лазейка. Я уже писал. Наша первая задача - безопасность.

На сайте магазина, который я писал, будучи школьником - попасть в админку можно было только при совпадении определенных условий, точном знании пароля и умении ловко поймать ссылку, в виде маленькой картинки, бысто бегающую по странице и рикошетящей под случайными углами smile.gif

Идею испортил местный админ - нагрузил комп процессами, из-за чего в страшном замедлении достаточно было совместить траектории ссылки и курсора мыши biggrin.gif

Спустя 11 часов, 6 минут, 47 секунд (1.12.2009 - 03:46) VolCh написал(а):
А чем плохи нативные шаблоны? сорри, если уже было

Спустя 8 минут, 53 секунды (1.12.2009 - 03:55) VolCh написал(а):
Цитата (Argnist @ 30.11.2009 - 13:42)
я все не могу поверить, что реально держать пароли в БД чем-то опаснее, чем в файлах))

Теорвер работает:
вероятность получить доступ к ФС пускай N, вероятность получить доступ к БД - M, но получив доступ к ФС мы автоматом получаем доступ к БД, а значит общая вероятность получения данных из БД заведомо выше, чем вероятность получения данных из ФС. точная форумла вроде N+M*(1-N)

Спустя 4 часа, 26 минут, 1 секунда (1.12.2009 - 08:21) Argnist написал(а):
для этого там слово реально smile.gif кстати от получения хешей паролей в БД опаснее не становится) я тервер тож проходил)

Спустя 39 минут, 58 секунд (1.12.2009 - 09:01) VolCh написал(а):
реально атаки типа SQL Injection самые распространенные wink.gif

Спустя 1 час, 5 минут, 48 секунд (1.12.2009 - 10:07) Argnist написал(а):
потому что все по Попову учат пыху) зато загрузка файла на сайт поопаснее будет)

Спустя 26 минут, 42 секунды (1.12.2009 - 10:33) twin написал(а):
VolCh
Цитата
А чем плохи нативные шаблоны? сорри, если уже было

В этом курсе не было. Они не плохи вовсе. По оптимальности это лучшее, что можно сделать на PHP. Но тут все дело в том, что я пытаюсь собрать движок, с которым будет очень просто работать людям, никогда его раньше не видевшим.
Как программистам, так и верстальщикам.

Вообще разделение логики и представления - притча воязыцах. Никому еще не удалось сделать это по настоящему красиво. И вряд ли удасться, потому что это тоже самое, что попытаться выяснить, что было раньше - курица или яйцо.

Если мы полностью удаляем php из шаблонов (по примеру СМАРТИ), то там появляется другая логика и другой язык программирования - язык шаблонов. Что крайне не радует верстальщиков (да и программистов тоже, если чесно признаться).

Если мы оставляем часть логики в шаблонах (нативный синтаксис), то разделение можно назвать весьма условным. Потому что и ифы и циклы остаются в шаблонах.

А хочется сделать так, что бы каждый занимался своим делом. Программисты кодили, верстальщики верстали. Потому есть третий вариант. По сути тот же нативный шаблон, но начисто лишенный логической составляющей. Потому что этого:
<?php foreach ($values as $value): ?>
<div class="item">
<
div class="title">
<?php if ($value->hasDate()): ?><?=$value->getDate()?><?php endif; ?>
<a href="<?= $value->getUrl() ?>"><?=
htmlentities($value->getTitle())
?></a>
</
div>
<
div class="content">
<?= htmlentities($value->getContent()) ?>
</div>
</
div>
<?php endforeach; ?>


обычный верстальщик пугается как пыльного мешка. А это:

<div class="item">
<
div class="title">
<?php echo $date; ?>
<a href="<?php echo href() ?>"><?php echo $title; ?></a>
</
div>
<
div class="content">
<?php echo $content; ?>
</div>
</
div>


ему гораздо привычнее. Потому что это:
 <?php echo $content; ?>

по сути своей тег. Пусть незнакомый, но не портящий общей картины. И не нужно думать: "а как поведет себя шаблон если... Или... И еще... И в цикле."

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

Evilsoul
Уже ответили, добавлю только немного. Кроме того, что в шаблонах есть динамический вывод, html все таки предполагает определенную структуру документа. Доктайп, заголовок, тело. А шаблон это кусок верстки.

Цитата
Где мы дели нашу кодировку и уровень ошибок?



Ну поставлю сейчас, чтоб не путать. Я думал, что лучше писать значимые участки листинга, чтоб не перегружать информацией уроки. Просчитался.

Цитата
Зачем нам нужна буферизация и как она будет работать?

Буфферизация, это такая штука, которая собирает весь вывод и упаковывает в переменную. Вот наглядно:
<?php
ob_start();
echo "Всякий текст";
$buffer = ob_get_contents();
ob_end_clean();

Если это запустить в браузере, никакого текста не будет. То есть функция echo не отправляет строку браузеру, а пишет в буффер, то есть в память. Если теперь сделать так:

<?php
ob_start();
echo "Всякий текст";
$buffer = ob_get_contents();
ob_end_clean();
echo $buffer;


То можно убедиться, что текст находится в переменной, куда мы считали его из буффера.
Для чего это надо. Для того, что бы не вызвать ошибку при отдаче заголовков, потому что заголовки должны отправляться раньше вывода. А теперь мы можем спокойно сделать это позже. Вот так:
<?php
ob_start();
echo "Всякий текст";
header("Content-Type: text/html; charset=utf-8");
$buffer = ob_get_contents();
ob_end_clean();
echo $buffer;


Вывод у нас по коду вроде как выше, но заголовок будет передан браузеру перед остальным текстом. Это касается так же старта сессий и установки кук.
Буфферизировать можно не только echo но и любой другой вывод. Допустим так:
<?php
ob_start();
?>
<div style="trxt" >
<?php
echo "Всякий текст";
?>
</div>
<?php
$buffer = ob_get_contents();
ob_end_clean();
echo $buffer;


Но самое главное, это то, что переменную $buffer, в которой собран весь вывод скрипта, можно теперь спокойно вывести в шаблоне. Что у нас и сделано.
Цитата
4) Почему используем такие комментарии
/**
* Installation of a key of access to files
* Установка ключа доступа к файлам
*/


Это стандарт для генератора документации. На двух языках потому что как оказалось, многострочные комментарии не дружат с латиницей. И пока мы тут учимся, будет перевод, что бы было проще. А в боевом исполнении русские комменты мы уберем.

Спустя 1 час, 51 минута, 58 секунд (1.12.2009 - 12:25) twin написал(а):
Загрузку такого файла мы не позволим делать юзеру. А лучшее средство от воровства - бедность. biggrin.gif Если нет предмета, который можно хакнуть, значит и хакать ни кто не будет. Мало ли что они изобретут там. А нет интерфейса - нет лазейки.

Спустя 51 минута, 9 секунд (1.12.2009 - 13:16) Shturman написал(а):
Цитата (twin @ 1.12.2009 - 09:25)
А нет интерфейса - нет лазейки.

За отдельную плату напишем FTP-интерфейс biggrin.gif

Спустя 6 дней, 22 часа, 28 минут, 25 секунд (8.12.2009 - 11:45) Wollff написал(а):
Цитата (twin @ 1.12.2009 - 09:25)
Загрузку такого файла мы не позволим делать юзеру.

Дак ведь это нужная в хозяйстве вешь. Например загрузка иизображений. Говорят, что если после загрузки их сразу пережимать, то опасности нет. Внедрённые в изображение подлые скрипты калечаться. Правда, нет?

Спустя 1 час, 48 минут, 49 секунд (8.12.2009 - 13:34) twin написал(а):
Првда. Только не вся. В идеале не нужно вообще пускать такие файлы, это мусор и портить диз начнут. По этому лучше загружать их в карантин, а потом перемещать с помощью графических библиотек. Тогда не картинки точно не попадут. Вот тут примерный принцип реализован.

Спустя 2 дня, 1 час, 18 минут, 34 секунды (10.12.2009 - 14:52) A.V. написал(а):
Временно выходит, что нечасто бываю в Сети, поэтому запаздываю сюда со своими попытками кодить.

Как я понял вариант задания.

1. Админ дожен создать txt-файл с уровнем доступа для каждого кандидата в
админы.
2. Пользователь должен вместо пароля ввести имя файла.
3. При совпадении имени и пароля ака имени файла данные заносятся в БД.


twin,

Так? Ощущение, что что-то недопонял, а ваше предложение по реализации найти не могу.

То есть создаётся текстовой файл, к примеру, invForUserIvanov.txt.
А для регистрации создаётся файл с формой прмерно такого вида:

<form name="form" action="указываем_скрипт_ли?" method="post">
<p>
Логин: <input type="text" name="userName"></p>
<p>
Пароль: <input type="password" name="userPassword"></p>
<p>
Уровень доступа: <input type="text" name="userInvite" size="2"></p>
<p><input
type="submit" value="Зарегестрироваться"></p>
</form>


...И файл с кодом вида:

  if(!empty($_POST['userName']) && !empty($_POST['userPassword']))
{
if(!empty($_POST['userInvite']))
{
/**
* Create array
* Создаём массив с POST-данными
*/


$arrUserPosts = array(
'name' => $_POST['userName'],
'password' => $_POST['userPassword'],
'invite' => $_POST['userInvite']
);


/**
* Open the invite-file to user
* Открываем invite-файл для отдельного пользователя.
*/


$file = $_POST['userPassword'];

if(file_exists($file))
{
$f = fopen($file, "r+");

/**
* Clean the file and record array
* Очищаем файл и пишем в него массив.
*/


ftruncate($f, 0);
fseek($f, 0, SEEK_SET);
fwrite ($f, serialize($arrUserPosts));
fclose($f);
rename($file, какое-либо_рандомное_имя?);

// Далее данные пользователя заносятся в БД. Либо другая часть программы.
// echo "OK!";

}
}

else echo "Отсутствует 'инвентарный номер'.";

}
else echo "Отсутствуют имя и пароль.";


Интересно. Хотелось бы дальше попробовать "развивать" это.


Спустя 17 минут, 50 секунд (10.12.2009 - 15:10) twin написал(а):
Вообще работу с POST данными еще не проходили. Там тоже интересный момент будет. По этому пока просто нужен файл, а его формирование из админки позже. В следующем уроке как раз планирую.

Спустя 9 дней, 18 часов, 5 минут, 5 секунд (20.12.2009 - 09:15) ApuktaChehov написал(а):
Вот и я наконец дополз.

  /**
* Создаем массив
*/

$arr = array(
'news' => array(
'title' => 'Новости',
'keywords' => 'Новости',
'description' => 'Это новостная страница'
),
'gallery' => array(
'title' => 'Галерея сайта',
'keywords' => 'Галерея, изображения',
'description' => 'Это галерея нашего сайта'
),
'products' => array(
'title' => 'Перечень продуктов',
'keywords' => 'Продукты',
'description' => 'Перечень продуктов'
)
);


/**
*Записываем в файл сериализованный массив
*/

file_put_contents ('skins/setup/content.txt', serialize($arr));

/**
*Извлекаем данные из файла
*/

$data = file_get_contents('skins/setup/content.txt');
$data = unserialize($data);

/**
*Распределение значений по переменным
*/

$title = $data[$GET['mod']]['title'];
$keywords = $data[$GET['mod']]['keywords'];
$description = $data[$GET['mod']]['description'];

Спустя 2 дня, 8 часов, 3 минуты, 41 секунда (22.12.2009 - 17:19) AmberLEX написал(а):
Цитата
Кардинально поменял функцию parseTpl()

Вот это класс! А то я уже начал над ней задумываться, больно уж большая она была. Регулярное выражение, if и цикл.

Спустя 21 час, 47 минут, 8 секунд (23.12.2009 - 15:06) denis39 написал(а):
А зачем фаблоны в формат tpl загонять?

Спустя 3 минуты, 39 секунд (23.12.2009 - 15:10) twin написал(а):
Ну обсуждали уже. HTML все таки ассоциируется с законченными, готовыми к бою и самостоятельными страницами. А tpl - это шаблоны. То есть полуфабрикат. Основная масса редакторов подсвечивает tpl, по этому удобно.

Спустя 7 часов, 40 минут, 9 секунд (23.12.2009 - 22:50) Krevedko написал(а):
прикрепи тут полный архив еще smile.gif

Спустя 5 минут, 57 секунд (23.12.2009 - 22:56) twin написал(а):
Все архивы я обновляю. Там в каждом уроке есть свежие.

Спустя 2 часа, 51 минута (24.12.2009 - 01:47) Krevedko написал(а):
ок. т.е. в пятом уроке уже полный фарш ?

Спустя 12 часов, 33 минуты, 8 секунд (24.12.2009 - 14:20) Хозяин Огня написал(а):
Цитата
Переключатель контроллеров в индексах модулей будем делать свичем.


Надо бы этот свич загнать в функцию, что-ли (много места занимает, а когда модулей будет больше...). Или лучше оставить для каждого модуля только его родной контроллер и дефолтный. Но тогда и шаблоны нужно подключать свичем, а то дефолтный контроллер подключили один, а ниже шаблон подключается другой.
А вообще не понимаю, зачем нужно подключение других контроллеров...

Спустя 23 минуты, 48 секунд (24.12.2009 - 14:44) twin написал(а):
Хозяин Огня
Цитата
Надо бы этот свич загнать в функцию, что-ли

Не думаю. Не так уж и много на самом деле, там в индексе кроме него практически ничего и нет. Это лишнее усложнение программы.
Цитата
Или лучше оставить для каждого модуля только его родной контроллер и дефолтный. Но тогда и шаблоны нужно подключать свичем, а то дефолтный контроллер подключили один, а ниже шаблон подключается другой.

Контроллеров в модуле обычно бывает несколько. Как в тех же новостях. Что касается подключения шаблонов в свиче - правильно мыслишь. Зачастую так и нужно делать. Но когда дойдем до кэширования, ситуация немного усложнится и такой вариант вряд ли будет оптимальным.
Цитата
А вообще не понимаю, зачем нужно подключение других контроллеров...

Дело в том, что в модуле может быть разнообразный функционал. Допустим модуль основного раздела: на главной странице могут быть новости, а на второстепенных нет. А весь остальной функционал страниц одинаковый. Тогда для главной мы подключим контроллер новостей, а для остальных не будем. Чтоб не тащить мертвый код в оперативку.

Спустя 3 часа, 34 минуты, 24 секунды (24.12.2009 - 18:18) Evilsoul написал(а):
Цитата (levitaly @ 23.11.2009 - 20:13)
Цитата (twin @ 23.11.2009 - 16:59)
$month_string[$row['month']]

Не совсем понял, что это значит!

А я вообще не понял что это значит(

По окончанию урока "Мета-данные не установлены" проверил файл, он с данными (взял из архива), ибо в уроке нет описания по их созданию а у меня с метаданными оч. туго., думал проблема в пути, нет все норм, корень есть
define('IRB_ROOT', str_replace('\\', '/', $_SERVER['DOCUMENT_ROOT']));

путь есть
if(!file_exists(IRB_ROOT .'/skins/setup/meta.txt'))

в чем проблема?
может у кого такое было?

Спустя 3 минуты, 3 секунды (24.12.2009 - 18:21) twin написал(а):
А скрипт в корне хоста?

Спустя 10 минут, 27 секунд (24.12.2009 - 18:32) Evilsoul написал(а):
/**
* Function of formation of meta-tags
* Функция формирования мета-тегов
*/


она что-ли?

да, есть, ты её в самом начале урока описывал, в дефаулте лежит smile.gif


Спустя 1 час, 4 минуты, 27 секунд (24.12.2009 - 19:36) twin написал(а):
Я имею ввиду весь сайт. Он в корне хоста или в какой то папке?
Посмотри что в IRB_ROOT


echo IRB_ROOT ;
пониже подключения конфиги и сравни с тем, где лежит весь скрипт.

Спустя 2 часа, 3 минуты, 58 секунд (24.12.2009 - 21:40) AmberLEX написал(а):
Функция parseTpl при проверке if(!empty($data)) возвращает $code А если переменная $data пустая, может null возвращать, а то как-то функция, которая ничего не возвращает странно)

Спустя 10 минут, 21 секунда (24.12.2009 - 21:50) twin написал(а):
Действительно. Лучше так:
/**
* Function of analysis of a template
* Функция разбора шаблона
*/

function parseTpl($cont, $data)
{

if(!empty($data))
{

extract($data, EXTR_PREFIX_ALL, 'tpl');

ob_start();
eval('?>'. $cont .'<?php ');
$cont = ob_get_contents();
ob_end_clean();

}
return $cont;
}

Спустя 34 минуты, 38 секунд (24.12.2009 - 22:25) AmberLEX написал(а):
Так тоже наверное не то. Он шаблон то обработает, выведет пустой, но в коде будет типа этого <a href="<?php echo $tpl_url; ?>"> - так и останется <? echo $tpl_var; ?>
Правда если $data пустая, то это вроде как ошибка в коде и нужно исправлять?

Спустя 1 час, 3 минуты, 46 секунд (24.12.2009 - 23:29) AmberLEX написал(а):
В переключателе контроллеров тогда так будет?
<?php

/**
* Generation of page of an error at access out of system
* Генерация страницы ошибки при доступе вне системы
*/

if(!defined('IRB_KEY'))
{
header("HTTP/1.1 404 Not Found");
exit(file_get_contents('../../404.html'));
}


/**
* The switch of modules
* Переключатель контроллеров
*/

switch($GET['rem'])
{
case 'read':
include IRB_ROOT .'/modules/news/read_controller.php';
$rem = 'read';
break;

case 'full':
include IRB_ROOT .'/modules/news/full_controller.php';
$rem = 'full';
break;

default:
include IRB_ROOT .'/modules/news/read_controller.php';
$rem = 'read';
break;
}

/**
* The switch of templates
* Переключатель шаблонов
*/

$tpl = IRB_ROOT .'/skins/tpl/news/'. $rem .'.tpl';
if (file_exists($tpl))
{
include ($tpl);
}
else
exit('The template <b>'. $tpl .'</b> is absent in the specification');

Спустя 18 минут, 11 секунд (24.12.2009 - 23:47) Хозяин Огня написал(а):
/**
* The switch of templates
* Переключатель шаблонов
*/

$tpl = IRB_ROOT .'/skins/tpl/news/'. $rem .'.tpl';
if (file_exists($tpl))
include ($tpl);
else
exit('The template <b>'. $tpl .'</b> is absent in the specification');


А разве это не заменили на простой инклуд?

Спустя 5 минут, 29 секунд (24.12.2009 - 23:52) Хозяин Огня написал(а):
Чёрти что! За изменениями не уследишь...
А действительно, что за $month_string?

Спустя 6 минут, 13 секунд (24.12.2009 - 23:59) AmberLEX написал(а):
Заменили переключатель контроллеров. А шаблоны тоже нужно переключать ведь.
Можно и так, как я понимаю:
<?php

/**
* Generation of page of an error at access out of system
* Генерация страницы ошибки при доступе вне системы
*/

if(!defined('IRB_KEY'))
{
header("HTTP/1.1 404 Not Found");
exit(file_get_contents('../../404.html'));
}


/**
* The switch of modules
* Переключатель контроллеров и шаблонов
*/

switch($GET['rem'])
{
case 'read':
include IRB_ROOT .'/modules/news/read_controller.php';
include IRB_ROOT .'/skins/tpl/news/read.tpl';
break;

case 'full':
include IRB_ROOT .'/modules/news/full_controller.php';
include IRB_ROOT .'/skins/tpl/news/full.tpl';
break;

default:
include IRB_ROOT .'/modules/news/read_controller.php';
include IRB_ROOT .'/skins/tpl/news/read.tpl';
break;
}
но тогда не будет проверки на отсутствие файла шаблона.

Спустя 4 минуты, 8 секунд (25.12.2009 - 00:03) AmberLEX написал(а):
Цитата
А действительно, что за $month_string?

$month_string находится в ru.php
    $month_string = array(
'01' => 'января',
'02' => 'февраля',
'03' => 'марта',
'04' => 'апреля',
'05' => 'мая',
'06' => 'июня',
'07' => 'июля',
'08' => 'августа',
'09' => 'сентября',
'10' => 'октября',
'11' => 'ноября',
'12' => 'декабря'
);

$row['month']
- это номер месяца
$month_string[$row['month']]
- это теперь месяц словом (т.е. значение элемента массива $month_string с ключем равным $row['month'] взятым из массива $row)

Массив $row можно посмотреть так:
    while($row = mysql_fetch_assoc($res))
{
echo '<pre>';
print_r($row);
echo'</pre>';
}
Там будут элементы:
[day] => 21
[month] => 12
[year] => 2009
Т.е. этой строкой:
$data['date'] = $row['day'] .' '. $month_string[$row['month']] .' '. $row['year'];
мы делаем 21 декабря 2009

Спустя 58 минут, 34 секунды (25.12.2009 - 01:01) Evilsoul написал(а):
Цитата (twin @ 24.12.2009 - 16:36)
echo IRB_ROOT ; 

D:/Apache/utf-8/wwwMeta-data are not established
все правильно указала на корень, там весе скрипты и папки

D:\Apache\utf-8\www\skins\setup
вот путь с адресной строки к мета.тхт

a:2:{s:4:"news";a:3:{s:5:"title";s:14:"Новости";s:8:"keywords";s:14:"Новости";s:11:"description";s:72:"Здесь находятся только горячии новости";}s:7:"gallery";a:3:{s:5:"title";s:14:"Галерея";s:8:"keywords";s:14:"Галерея";s:11:"description";s:40:"Посетите нашу галерею";}}
вот сам "meta.txt"

и я думаю дело не в пути, ибо было бы так: There is no file with the data for meta tags, а он мне пишет что Meta-data are not established не установлены, видать что-то с тхт или с данными. Как ты их туда записывал? Дай пожалуйста скрипт если есть.


Спустя 15 минут, 53 секунды (25.12.2009 - 01:17) Evilsoul написал(а):
Цитата
Цитата
А действительно, что за $month_string?

$month_string находится в ru.php


ёёёё, так вот в чем все мои беды могут быть, по окончанию этого урока у меня в ru.php только вот это есть:

<?php
$language = array(
'news' => 'Новости',
'gallery' => 'Галерея'
);
?>


а в архиве:

   if(!defined('IRB_KEY'))
{
header("HTTP/1.1 404 Not Found");
exit(file_get_contents('../404.html'));
}

define("IRB_NO_CONNECT", "В настоящий момент сервер базы данных не доступен, поэтому корректное отображение страницы невозможно.");
define("IRB_NO_DB_SELECT", "В настоящий момент база данных не доступна, поэтому корректное отображение страницы невозможно.");

define('IRB_ALL_NEWS', 'Все новости');
define('IRB_FULL_NEWS', 'Полностью');


$language = array(
'news' => 'Новости',
'gallery' => 'Галерея',

);



$month_string = array(

'01' => 'января',
'02' => 'февраля',
'03' => 'марта',
'04' => 'апреля',
'05' => 'мая',
'06' => 'июня',
'07' => 'июля',
'08' => 'августа',
'09' => 'сентября',
'10' => 'октября',
'11' => 'ноября',
'12' => 'декабря'
);


во многих скриптах тоже куча констант и функций у меня отсутствует(((


Твин, может с чистого листа все перепишем, я мог бы по мере своих возможностей помочь в описании не сложных частей кода.

Спустя 35 минут, 3 секунды (25.12.2009 - 01:52) AmberLEX написал(а):
Там тех функций десяток всего. И констант около того.
Я разбирался с каждой функцией и писал все с нуля, включал debug чтоб переменные смотреть и усложнял по урокам. Теперь четко представляется вся структура в целом в голове и что где делается. Если где-то че-то меняется я точно знаю, что есть у меня на данный момент и что нужно изменить или добавить и где.

Спустя 40 минут, 17 секунд (25.12.2009 - 02:33) Evilsoul написал(а):
Дядька, ты запустил в работу три сайта, соответственно у тебя уже опыт есть, возможно ты даже использовал MVC с ООП. А я только начал учится, где-то месяц изучаю PHP, мне довольно таки тяжело разобраться.

К примеру:
в начале уроков в индексе
include './variables.php';  


в последствии в индексе
   include IRB_ROOT .'/variables.php';


где, откуда взялась эта константа? напрягаем мозги и думаем ... ага, у нас константы в конфиге, идем туда, черт, здесь ничего нет, от куда же оно взялось? опять напрягаем мозги ... зайду ка я в этот архивчик, может там ответ есть? в точку! есть, вот она
define('IRB_ROOT', str_replace('\\', '/', $_SERVER['DOCUMENT_ROOT']));

но почему мы не определили её сразу? так бы проще было и понять и работать, опять напрягаем мозги .............................. непонятно, скорее всего просто у Твина много работы, он по форуму везде всем помогает и подсказывает и еще уроки ведет (низкий ему поклон за это), естественно в такой суматохе можно изменить код и не изменить его в уроках.

Я к чему собственно веду, если бы код в уроках и описания к нему на 100% соответствовали архиву то можно было бы избежать многих лишних и не нужных вопросов на которые и Твин и ты и многие другие пытаются дать ответ а в итоге выходит что просто забыл (образно говоря) поставить точку.

Спустя 13 минут, 9 секунд (25.12.2009 - 02:46) AmberLEX написал(а):
Может ввести еще константы (не знаю как у Вас там планируется)
В ru.php
define('IRB_SITE_NAME', 'IRBIS CMS');

В config.php
/**
* Separator symbol for title
* Символ для разделения названий в заголовке
*/

define('IRB_SEPARATOR', '|');
В index.php
	/**
* We connect a file of the general functions
* Подключаем файл общих функций
*/

include IRB_ROOT . '/libs/default.php';

$title = getMeta('title') . ' ' . IRB_SEPARATOR . ' ' . IRB_SITE_NAME;
$keywords = getMeta('keywords');
$description = getMeta('description');
Т.е. в строке заголовка окна для модуля новостей будет (read_contrоller.php):
Новости | IRBIS CMS

А в full_contrоller.php после $news = parseTpl($tpl, $data);
// Строка заголовка окна для новости
$title = $data['subtitle'] . ' ' . IRB_SEPARATOR . ' ' . $title;
Тогда в строке заголовка будет:
Название самой новости | Новости | IRBIS CMS
В общем как-то так smile.gif Подумать как будет формироваться строка заголовка.

Спустя 3 дня, 18 часов, 37 минут, 31 секунда (28.12.2009 - 21:23) Fillzest написал(а):
Спасибо за уроки twin , хорошое пособие для начинающих и может не только для начинающих smile.gif

Спустя 17 часов, 42 минуты, 5 секунд (29.12.2009 - 15:05) Хозяин Огня написал(а):
Суть домашнего задания - осуществление управления содержимым файла meta.txt из админки, я правильно понял?

Спустя 5 минут, 56 секунд (29.12.2009 - 15:11) twin написал(а):
Да, именно. Только учесть, что массив нужно сформировать для разных страниц. Причем так, что бы можно было без особых хлопот эти страницы добавлять и удалять.

Спустя 13 часов, 9 минут, 22 секунды (30.12.2009 - 04:21) AmberLEX написал(а):
Че-то вообще не то.
Мета данные у нас в файле setup.txt, т.е. это данные для каждого модуля.
В админке, когда мы нажимаем на меню setup(установка) мы можем отправить данные из формы на обработку контроллеру setup_controller.php
Т.е. нам нужно указывать для какого модуля эти данные.

Тут вариантов много. Я понимаю это так:

Сверху меню:
Установка | Новости | Галерея

Если мы нажимаем, например, на Новости, то там будет подменю:
Метаданные модуля | Добавить новость

Если мы нажимем на Метаданные модуля, то мы идем в контроллер, который выводит в форме эти данные (если они есть) Если нет, то заполняем и сохраняем.

Если мы нажимаем на Установка, то... как бы и не нужна. Т.е. для каждого модуля можно заполнять метаданные в самом модуле получается.

В Установка можно вывести список всех метаданных всех модулей, например и оттуда их редактировать (типа дубляжа, чтоб удобнее было).
Примерно так?

Спустя 7 минут (30.12.2009 - 04:28) twin написал(а):
Дело в том, что метаданными оперируют сеошники, а им не всегда удобно бегать по разделам сайта, которые им может и не нужны совсем. Допустим новости оптимизировать - лишне, они и так всегда свежие, в галерее одни картинки - неча там им делать... Прайсы, контакты и т.д.
А вот один раздел админки, посвещенный всем установочным данным (метуха, robot.txt, sitemap и так далее) очень удобен.
По этому нужно в этом модуле делать разделы - для метаданных (один контроллер) и так далее. А в них уже свое управление. С ручным обозначением страниц или лучше с автоматическим - тут как уже сможем. smile.gif

Спустя 17 минут, 7 секунд (30.12.2009 - 04:45) AmberLEX написал(а):
Ну и с мета не понял.
Если есть галерея с категориями: "цветы", "деревья", "листья" и т.п.
На странице "Галерея" выводится последние добавленные фото со всех категорий.
Че бы для модуля галерея не сделать ключевые слова (общие) "цветы", "деревья", "листья", А для самой категории "цветы", например, набор ключевых слов для цветов?
Ну и для новостей, если на странице 5 новостей (по 50 слов из каждой), для этой страницы надо же какие то ключевые слова и описание писать или пусто будет?

Спустя 9 минут, 2 секунды (30.12.2009 - 04:54) twin написал(а):
Новости обычно в чистом виде не выводят... Крайне редко. Обычно это сопровождается еще чем то. По этому мета данные нужны не для модуля новостей, а для страницы, на которой они присутствуют. Там может быть задействовано еще несколько модулей.
Так же и с другими. Тот же модуль регистрации вообще не требует установочных данных.

Модуль настроек должен давать возможность устанавливать мета-данные странице, а не модулю.

Спустя 11 минут, 4 секунды (30.12.2009 - 05:05) AmberLEX написал(а):
Так а что мы тогда делали? Я думал это метаданные для модуля (т.е. общей страницы, где несколько новостей, или статей и читать сам список новостей из одной таблицы и метаданные для этой общей страницы из другой таблицы накладно)

Если это новость, то в базе сделать поля keywords и description для этой новости (т.е. страницы)
Если это страницы типа Главная, О нас или Скидки, то это тоже выходит таблица в БД для этих страниц. Для этой таблицы тоже сделать поля keywords и description. Тогда вообще не нужен setup.txt Мы все равно в запросе читаем страницу и для нее будут метаданные, вот заодно их и прочитаем. Зачем возиться с отдельным файлом и читать оттуда?
Или, на крайняк, сделать отдельную таблицу в БД, например, meta для keywords и description и связать ее с остальными. Т.е. когда читается страница Новости или О нас, то соответственно читается и из той таблицы метаданные и все в одном запросе (ну это геморроя больше и медленнее).

Спустя 4 часа, 42 минуты, 19 секунд (30.12.2009 - 09:47) twin написал(а):
Нет, не так немного.

Модуль это модуль. Какой то функционал. Допустим те же новости. Этот модуль мы сможем прикрутить наряду с другими модулями (регистрация к примеру, модуль статических страниц, что бы добавить помимо новостей какой то текст, модуль отзывов и так далее) к главной странице. Из этих же модулей можно будет слепить любую другую страницу, как из конструктора Лего. К примеру в той же галерее можно сбоку пустить ленту новостей.
То есть модуль и страница - совершенно разные вещи. А мета данные нам нужны именно на странице - то есть на выдаче.

Наверное тут проблема терминологии. Не mod должна называться переменная GET а как то иначе, чтоб не вводить в заблуждение. Скорее всего page, а вот постраничку обозначить list. Просто как то привыкли уже с чьей то "легкой" руки, что раз пагинатор, то значит page... Подумать нужно над этим тонким моментом.

Спустя 1 час, 21 минута, 51 секунда (30.12.2009 - 11:09) AmberLEX написал(а):
Ну можно и page, то не принципиально. Просто все равно я не очень понял.
Захожу на сайт и там есть страницы, нахожу нужную и читаю основной текст (это может быть статья, новость, позиция товара и т.п.). Для неё нужны свои уникальные keywords и description. Сайт и состоит из таких уникальных текстов. Обычно эта инфа находится в БД, тогда в БД можно добавить поля с keywords и description - это уникальные слова и описание для этого конкретного текста. А то что находится на станице еще: комментарии, голосование, погода, анекдот, три последние новости - это нас не интересует и по идее в ключевые слова и описание этой страницы не входит.
Т.е. есть основная инфа и налеплено разных модулей (или блоков, виджетов, как их там правильно называть) и для этой инфы нужны кейворды и описание.
А для общих страниц (модулей) типа последних новостей, картинок, которые ведут к нужной нам инфе, тогда они не особо и нужны.
На сайтах я смотрел, для таких страниц или пусто или общие кейворды и описание для всего сайта выводят + название модуля + слоган сайта.
Вообщем я как-то так это представляю)
ЗЫ люди уже наверное воТку пьют или похмеляются после корпоративов, а я тут в кейвордах разобраться не могу biggrin.gif

Спустя 1 час, 22 минуты, 12 секунд (30.12.2009 - 12:31) twin написал(а):
Вобщем смысл простой. Не наша это забота - ставить тайтлы на каждую страницу или на основные. Это пусть сеошники голову греют. Наша задача сделать возможность легко и просто этим управлять. Есть страница - должна быть возможность установить метатеги.
Базу для этих целей юзать как то расточительно мне кажется. По этому вот и задача.

Спустя 2 часа, 29 минут, 20 секунд (30.12.2009 - 15:01) AmberLEX написал(а):
Выходит нам нужно в админке в одном месте дать доступ к удобному заполнению метатегов для страниц для которых это предусмотрено. Типа карты сайта - нажал на нужную страницу (название) - заполнил метатеги?
А если если их штук 200, то нужно удобно расположить, они ведь могут принадлежать к разным модулям (страницы статей, товаров, услуг и т.п.) Не лепить же их списком все подряд по алфавиту.

И тут еще вопрос: ob_start() хранит данные в буферной памяти - что это за память и сколько ее нам доступно? Я так понимаю на сервере. У нас почти весь сайт так построен (через ob_start) Мы для каждой страницы (нажатой ссылки) будем читать весь файл meta.txt в буфер, хотя нужны только для конкретной страницы? Или они в буфер не читаются? Можно разъяснить, а то я че-то вообще уже запутался smile.gif

Спустя 2 часа, 38 минут, 3 секунды (30.12.2009 - 17:39) twin написал(а):
Размер буфера ограничен общим размером оперативной памяти, выделяемоой на скрипт. В него пишется только вывод. То есть то, что выдает конструкция echo или прямой вывод, HTML.
Файл будет весь записан в оперативку, но не в буфер. Но он не будет особо большим.
Впрочем если есть сомнения, то в бд используются те же самые файлы.))
Тут нам не нужна обработка, не нужна сложная выборка или поиск. По этому гонять два сервера из за пары статичных строк не выгодно.

Спустя 4 дня, 19 часов, 56 минут, 57 секунд (5.01.2010 - 13:36) Krevedko написал(а):
Вот бы еще с картинками rolleyes.gif

Спустя 1 день, 21 час, 42 минуты, 19 секунд (7.01.2010 - 11:18) Хозяин Огня написал(а):
К аттачам лучше делать приписку типа "последнее изменение хх.хх.хххх".

Спустя 34 минуты, 8 секунд (7.01.2010 - 11:52) twin написал(а):
Все дело в том, что вы, ребята, первопроходцы и соавторы. Я, в процессе, шлифую уроки. И они (я надеюсь) становятся более понятными для тех, кто только начал.
А путать их историей изменений не хочется. По этому я все изменения выношу в отдельную тему. Просто послеживайте за ней. Вам, тем кто уже давно тут плавает и помогает писать, я думаю не стоит разжевывать в манную кашу. Далеко не дети уже. smile.gif

Пользуясь случаем, хочется поблагодарить всех, кто принимает активное участие в разработке курса, без вас было бы так же непонятно, как в первой редакции. А сейчас вопросов на порядок меньше при примерно той же посещаемости. Всем респектище!!! smile.gif

Спустя 3 минуты, 51 секунда (7.01.2010 - 11:56) Хозяин Огня написал(а):
twin, тебе спасибо))

По домашке.
Значит мы должны в setup_controller.рнр получить массив из файла мета.тхт и полученные постом данные забить в ему в конец, так?
И тогда придётся сверять ключи - если постом в определённом инпуте пришло news, то заменяем им старый news и его значение...как-то так?
Если да, какие функции для работы с массивами тут понадобятся?


Спустя 4 минуты, 19 секунд (7.01.2010 - 12:00) twin написал(а):
Не, так не пойдет. Я не смогу за ручку водить всю жизнь. Сами думайте, это только семечки. И функции есть все в мануале, и алгоритмы продумывайте.

Спустя 38 минут, 13 секунд (7.01.2010 - 12:38) Хозяин Огня написал(а):
Твин, прав, прав...

Добавление новой страницы сделал:


if (file_exists(IRB_ROOT .'/skins/setup/meta.txt'))
{
$metta = unserialize(file_get_contents(IRB_ROOT .'/skins/setup/meta.txt'));
}

if($ok)
{
irbdebug($POST);
$page = $POST['value4'];
$title = $POST['value1'];
$keywords = $POST['value2'];
$description = $POST['value3'];

$metta["$page"] = array(
'title' => $title,
'keywords' => $keywords,
'description' => $description
);

file_put_contents(IRB_ROOT .'/skins/setup/meta.txt', serialize($metta));
}


Над изменением теперь надо подумать.

Спустя 2 часа, 29 минут, 27 секунд (7.01.2010 - 15:08) AmberLEX написал(а):
Честно? Вот ниче я так понять и не могу в чем задача? Сейчас у нас читаются мета-теги для переменной mod и в зависимости от того какая mod - выбираются мета. Т.е. в функции getMeta читается элемент массива по mod - и все.
При чем здесь страницы сайта? Для любой новости или страницы галереи одна переменная mod и одни и те же мета выходят.
Если делать для каждой страницы, то нужно определиться как и что конкретно выглядит. Они заранее определены или их можно добавлять. Страница с каждой отдельной новостью - это отдельная другая страница. Не вижу я вообще никакой структуры, а добавлять что не зная что и куда....
Ну добавим мы мета в массив, сделаем удаление и добавление из этого массива, а к страницам это как привязывать, какие они будут, кто понял-то что нужно?

Спустя 17 минут, 47 секунд (7.01.2010 - 15:26) twin написал(а):
А где написано, что там должна быть обязательно переменная $mod... Поставь $rem. Или $var... Думай.

Спустя 1 час, 4 минуты, 34 секунды (7.01.2010 - 16:30) Хозяин Огня написал(а):
AmberLEX, не понимаю в чём проблема.
Через сетап устанавливаем "главные" титлы и т.д.
С помощью твоего $title = $data['subtitle'] . ' ' . IRB_SEPARATOR . ' ' . $title; делаем титлы для производных страниц.
Всё красиво, всё работает. Или я чего-то недопонимаю?

twin, ну как домашка-то? Принимается?


Спустя 7 минут (7.01.2010 - 16:37) twin написал(а):
Сёдня кодить грех ))) А серьёзно - завтра посмотрим. Я за столом уже))

Спустя 20 часов, 51 минута, 3 секунды (8.01.2010 - 13:28) AmberLEX написал(а):
Цитата
А где написано, что там должна быть обязательно переменная $mod...
в коде smile.gif
То, что мы имеем сейчас - это новости и галерея.
Написать serialize или unserialize не проблема как бы.
Просто я не вижу общей структуры сайта. Тогда нужно поставить задачу конкретно, что есть и что должно получиться. Как это сделать - каждый по-своему реализует и выложит здесь для обсуждения.

Думаю...
Вот Вы говорите, что я забегаю на перед, но как-то привычнее идти от общего к частному. Если так уж пошло (создание CMS), то нужно для начала описать требования к ней и задачи, которые она будет выполнять. Я так понимаю, у Вас это представление есть, но вы не делитесь biggrin.gif

Как понимаю это я.
Большинство сайтов делается стандартных.
1. Сайт-визитка. 1-3 страницы (О компании, Контакты, Новости) Но если визитка - то на одной обычно. Делая даже 1-2 сайта-визитки в неделю сумма выйдет равной примерно одному серьезному сайту (магазина, например), который можно делать месяц и получить ту же сумму и кучу глюков smile.gif
2. Средний сайт на котором обычно находятся новости, статьи, отдельные страницы, гостевая, галерея, голосования, обратная связь, FAQ и т.п. Если есть своя "типа CMS", то он тоже программируется от двух-трех дней.

Дальше продолжать не буду (там нужно подумать и классифицировать).

Получается нужно поставить задачу (если это CMS): сделать основные модули (гостевой, галереи, голосований, новостей, статей и т.п.) Они будут подключаться и отключаться если нужно. (Например, как сделано на Юкозе, не дай бог на нем что-то делать smile.gif ), но мысль там интересная.

Теперь: что мы будем считать страницами и для каких страниц нужны мета-теги? Оговаривается это в ТЗ или в CMS это можно будет указывать через админку?

Мы ищем конкретную инфу в инете, нас интересует единица информации (страница текста или видео или картинка) Все остальное, что там присутствует - дополнительная инфа, навигация, блоки с последними новостями, новыми видео - присутствует на странице, но вспомогательно.

Если за станицу сайта брать запись в БД - это именно та инфа, которая составляет наполнение сайта и та, которую, возможно ищет пользователь, то для нее и нужно составлять мета-теги (но тоже не для всех записей).

Т.е. если это новость, то для нее нужно составить мета-теги, если статья, то для нее.
Если у нас есть CMS, есть написанные модули, то принцип формирования мета нужно оговорить и определиться со структурой. Например, мета для любой страницы формируется исходя из переменной mod и id записи в БД.
Можно написать общую функцию (то, что есть сейчас), которя выводит мета по mod. Можно вообще любую функцию написать (хоть по mod, var), но это нужно же как-то привязать к тому, что есть или что будет. Какие-то правила сформулировать.

Цитата
наша это забота - ставить тайтлы на каждую страницу или на основные... Наша задача сделать возможность легко и просто этим управлять. Есть страница - должна быть возможность установить мета-теги.


Вот. Есть у нас сайт, с немереным количеством страниц, которые находятся в разных разделах, модулях и как представить это управление через админку с пунктом меню "Мета данные"?

Можно сделать просто. Две таблицы: категории и страницы. Вложенность неограниченная (больше 3-х наверное не понадобится) Из всего этого можно формировать интерфейс сайта: выстроить это в меню. Добавил категорию новости в ней страницы, добавил статьи - в ней страницы. Добавил страницу "Мои фотографии" - в ней страница с фотками, добавил "Контакты" - поместил отдельно в меню, добавил страницу "Рыбалка" - отдельно в меню, в ней вложенные страницы: "Как ловить", "Что делать если не поймал", "Злачные места", "Как правильно опохмелиться". Т.о. можно сделать большой информационный сайт, вообще не напрягаясь и для каждой страницы без проблем вписывать мета.

Такое ощущение, что я один не понимаю, что делать нужно и что получится на выходе. Написать функцию для мета-тегов и чтоб через админку для страниц. Для каких, какие будут страницы, модули. Кто и как их будет добавлять или это программист будет делать. Определил в БД 5 страниц и все, для них и заполняйте все. Как это связано с БД. Если это общая функция, то определить какие у нее входные параметры и строить страницы или модули так, чтоб эта функция понимала от куда инфа и по ней генерила мета. Но это же как-то определить заранее нужно.
Например, если это страница галереи и мета не нужны, то функция ничего и не выдает.
Если в админке есть возможность добавлять мета, то эти мета для какой-то страницы конкретной должны быть, т.е.нужно добавлять тогда и соотв. страницу.
Эта страница может в каком-то модуле. При ее редактировании, должна быть вожможность редактировать для нее и мета-данные. В свою очередь, при редактировании мета, должен быть удобно организван и выбор страницы, для которой они изменяются. В общем вопросов много, а задача, выходит, написать функцию чтения или редактирования массива мета выходит, а ее интерфейс, к чему и как ее привязать непонятно. Может это как-то оговорить?

P.S. И пользуясь случаем, тоже хочу всех поблагодарить, особенно twin-а Много нового узнал и уже в своих наработках достаточно поисправлял в соответствии с курсом. Много ценных мыслей и вопросов, что очень помогает пониманию материала. Может я действительно тороплюсь, но о-о-очень хочется к практичному приблизится и узнать, что же получится и применить smile.gif

Спустя 4 часа, 59 минут, 32 секунды (8.01.2010 - 18:28) twin написал(а):
Очень основательно. smile.gif
Дело в том, что я имел опыт проведения таких курсов и вывел одну закономерность. Как только начинаешь объяснять архитектуру, сразу же проподает весь интерес. А вот когда что то начинает маленько шевелиться и работать - виден результат. И это помогает не отчаяться - мол мне этого никогда не понять.
Ну значит настало время - в следующем уроке постараюсь прорисовать структуру подробно, чтоб была видна общая картина.

Спустя 18 часов, 3 минуты, 18 секунд (9.01.2010 - 12:31) Хозяин Огня написал(а):
twin, для админки нужен свой главный шаблон - admin_index.tpl(например)?
Я его сейчас сделал, т.к. нужно было вставить надпись "Админ панель" над меню, может потом ещё чего-нить придётся добавить, чего нет в основном шаблоне...

Спустя 7 минут, 7 секунд (9.01.2010 - 12:38) twin написал(а):
Тут дело вкуса. Надпись можно в меню вставить, оно все равно отдельное. Тогда главный шаблон один останется. А можно админку в другом дизайне сделать. Это зависит от конкретных условий.

Спустя 1 день, 4 часа, 27 минут, 26 секунд (10.01.2010 - 17:06) twin написал(а):
Никуда, просто сейчас время дурацкое. Полувыходные, полуаврал. Просто совсем нет времени заниматься. Даже форум читать нет времени.
Сейчас все вернется в нормальный ритм, я продолжу. smile.gif

Спустя 1 час, 2 минуты, 15 секунд (10.01.2010 - 18:08) AmberLEX написал(а):
Хозяин Огня, вот если бы еще и архив с БД был biggrin.gif

Спустя 10 минут, 48 секунд (10.01.2010 - 18:19) Хозяин Огня написал(а):
AmberLEX, ок, перезалил c дампами;)

Спустя 13 часов, 38 секунд (11.01.2010 - 07:19) Shturman написал(а):
Я потихоньку возвращаюсь biggrin.gif

Цитата (AmberLEX @ 10.01.2010 - 23:37)
Хотелось бы сделать групповое удаление новостей.
Но тогда с переменными $POST не очень хорошо - чтобы отмечать public и те новости, которые на удаление, понадобились два вида переменных value и del, чтобы отличать для кого галочки установлены. Все одной кнопкой. В общем смотреть нужно, может как-то переделать, чтоб выбирать действие.
Архив прикрепил.


Кстати, мысль возникла - а зачем удалять новости? Может сделать флажок show? Если 1 - показываем новость, если 0 - не показываем. Просто часто бывает, что удалил, а потом восстановить хочется, но нечего уже.

Спустя 26 минут, 13 секунд (11.01.2010 - 07:45) twin написал(а):
Вообще там есть поле `public` как раз для этой цели.

Спустя 23 часа, 24 минуты, 46 секунд (12.01.2010 - 07:10) Shturman написал(а):
Перечитал тему еще раз и мысль возникла...
А что если сделать элементарно форму для создания универсальных мета-наборов?
Т.е. в админке будет Установка мета-данных - страница, состоящая из двух частей:
первая часть - создание/удаление/редактирование наборов
вторая часть - применение к страницам

Т.е. у нас будет папочка с метафайлами, создаваемыми из админки и один файлик (например metasetup.txt) где будет список страниц и соответствующих им метафайлов.
Причем, можно будет выводить список страниц просто перебирая файлы в директории (даже в виде дерева нарисовать) и напротив каждой - SELECT со всеми существующими метафайлами. Пробежался по всем модулям по порядку, нажал один раз "Применить" и готово.

Спустя 13 часов, 37 минут, 2 секунды (12.01.2010 - 20:47) Хозяин Огня написал(а):
Shturman
Цитата
Причем, можно будет выводить список страниц просто перебирая файлы в директории


Cтоп. Как это мы можем перебирать страницы? Разве у нас на каждую страницу отдельный файл? Они генерируются контроллерами...

Спустя 12 часов, 58 минут, 24 секунды (13.01.2010 - 09:46) Shturman написал(а):
Цитата (Хозяин Огня @ 12.01.2010 - 17:47)
Cтоп. Как это мы можем перебирать страницы? Разве у нас на каждую страницу отдельный файл? Они генерируются контроллерами...

Ну это понятно, но ведь могут быть и статичные страницы. По желанию клиента запихано может быть что угодно.
А те, что генерируются контроллерами все-равно однотипные - для них один набор подходить будет.

Спустя 9 часов, 35 минут, 4 секунды (13.01.2010 - 19:21) Хозяин Огня написал(а):
twin, вот - http://tuitkarshi.comxa.com/admin/setup/read/1/1
попробуй создать данные для новой страницы, а потом изменить их. Тогда в массиве между keywords и description образуется перенос строки(сейчас это видно по данным для guestbook). Я всю голову себе сломал - не пойму почему так происходит...

Спустя 1 час, 34 минуты, 16 секунд (13.01.2010 - 20:55) twin написал(а):
Немного не понял, где изменить. Но оно и не мудрено, у нас Старый Новый Год. Завтра Будем досконально разбираться и писать новый урок.
А по переносу строки могу предположить, что у тебя этот перенос удваивается. Нужно или обрезать на выводе, или на вводе. Часто такая проблема возникает с функцией file()
Хотя если чесно, я код не смотрел.

Спустя 1 час, 7 минут, 6 секунд (13.01.2010 - 22:02) Хозяин Огня написал(а):
Я не юзал file(), а как ты говорил - file_put_contents
А изменять так - выбираешь страницу из выпадающего меню, первый инпут оставляешь пустым, остальные три - заполняешь.
Тогда в ирбдебаге становится виден этот перенос. В принципе всё работает, но если перенести модифицированный таким образом файл meta.txt на другой хостинг, РНР будет ругаться, что массив кривосериализован.

Спустя 3 дня, 10 часов, 4 минуты, 14 секунд (17.01.2010 - 08:06) twin написал(а):
Может это из за разных осей... Конец строки в винде и юниксе обозначаются по разгому. В юниксе \n в винде \r\n Попробуй сериализовать массив прямо на хостинге. Или посмотри операционки.

Кстати говоря - обратите внимание, что это теперь 7-й урок. Я написал енще один и вставил до. Теперь тот 6-й, а этот 7-й.

Спустя 4 дня, 10 часов, 4 минуты, 44 секунды (21.01.2010 - 18:11) Хозяин Огня написал(а):
Вопрос касательно галереи.
Разве конструктивно хранить уменьшенную копию изображения? Ведь можно его и так уменьшить при выводе. А так лишний вес да плюс лишние проблемы с загрузкой из админки будут.

Спустя 22 минуты, 3 секунды (21.01.2010 - 18:33) twin написал(а):
Ресайз на лету очень расточительная и долгая операция. Превьюшку хранить гораздо выгоднее.

Спустя 1 минута, 37 секунд (21.01.2010 - 18:35) twin написал(а):
И не циклитесь на модулях, они только для примера. Мы потом будем разрабатывать более серьёзные модули. Сейчас нужно с основой разобраться. smile.gif
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.