четверг, ноября 11, 2010

Глобальная переменная $_REQUEST в php

Заметил интересное поведение в глобальной переменной
$_REQUEST в php, похоже она создается по запросу
~$ php -r 'echo (int)isset($GLOBALS["_REQUEST"])."\n";'

ответ 0, но если
~$ php -r '$_REQUEST;echo (int)isset($GLOBALS["_REQUEST"])."\n";'

ответ уже 1

понедельник, ноября 08, 2010

Java - кофе



Теперь я не только пишу Java, но и пью её.

понедельник, августа 30, 2010

Mysql ERROR 1005 (HY000): Can't create table (errno: 150)

Уже который раз спотыкаюсь об одни и те же грабли, решил записать.

т.е. после создания таблиц:

CREATE TABLE sf_guard_user
(
id BIGINT AUTO_INCREMENT,
first_name VARCHAR(255),
last_name VARCHAR(255),
email_address VARCHAR(255) NOT NULL UNIQUE,
username VARCHAR(128) NOT NULL UNIQUE,
algorithm VARCHAR(128) DEFAULT 'sha1' NOT NULL,
salt VARCHAR(128), password VARCHAR(128),
is_active TINYINT(1) DEFAULT '1',
is_super_admin TINYINT(1) DEFAULT '0',
last_login DATETIME, created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
INDEX is_active_idx_idx (is_active),
PRIMARY KEY(id)
)ENGINE = INNODB;

CREATE TABLE sf_guard_user_profile
(
id BIGINT AUTO_INCREMENT,
user_id BIGINT, first_name VARCHAR(20),
last_name VARCHAR(20),
email VARCHAR(255),
email_hash VARCHAR(255),
INDEX user_id_idx (user_id),
PRIMARY KEY(id)
) ENGINE = INNODB;


я пытаюсь создать ключи:


ALTER TABLE sf_guard_user_profile
ADD CONSTRAINT sf_guard_user_profile_user_id_sf_guard_user_id
FOREIGN KEY (user_id)
REFERENCES sf_guard_user(id)
ON DELETE CASCADE;

и получаю ошибку ERROR 1005 (HY000): Can't create table (errno: 150)
mysql говорит, что не может найти поле на которое ссылаемся

mysql> SHOW ENGINE INNODB STATUS;
...
100830 20:59:41 Error in foreign key constraint of table s1/#sql-477_152:
FOREIGN KEY (user_id) REFERENCES sf_guard_user(id) ON DELETE CASCADE:
Cannot find an index in the referenced table where the
referenced columns appear as the first columns, or column types
in the table and the referenced table do not match for constraint.
Note that the internal storage type of ENUM and SET changed in
tables created with >= InnoDB-4.1.12, and such columns in old tables
cannot be referenced by such columns in new tables.
See http://dev.mysql.com/doc/refman/5.1/en/innodb-foreign-key-constraints.html
for correct foreign key definition.
...


mysql это не нравится, отсюда и ошибка, хотя пишет что не может найти поле, а оно есть.
Дело оказывается в том, что в symfony при генерации схемы нет проверки на размерность типов для внешних ключей, т.е. если указать разные размерности для ключевых полей, то будет ошибка, т.е. вместо:

sfGuardUserProfile:
tableName: sf_guard_user_profile
columns:
user_id: integer(4)
first_name: varchar(20)
last_name: varchar(20)
email: varchar(255)
email_hash: varchar(255)
relations:
Users:
class: sfGuardUser
refClass: sfGuardUserGroup
local: group_id
foreign: user_id
foreignAlias: Groups
sfGuardUser:
type: one
foreignType: one
class: sfGuardUser
local: user_id
foreign: id
onDelete: cascade
foreignAlias: Profile

надо :

sfGuardUserProfile:
tableName: sf_guard_user_profile
columns:
user_id: integer
first_name: varchar(20)
last_name: varchar(20)
email: varchar(255)
email_hash: varchar(255)
relations:
Users:
class: sfGuardUser
refClass: sfGuardUserGroup
local: group_id
foreign: user_id
foreignAlias: Groups
sfGuardUser:
type: one
foreignType: one
class: sfGuardUser
local: user_id
foreign: id
onDelete: cascade
foreignAlias: Profile


а именно поле user_id должно быть таким же как в у sfGuardUser

среда, июня 02, 2010

Как сделать слайд-шоу для рабочего стола gnome

В ubuntu 9.10 появились обой рабочего стола в виде слайд-шоу



его пример лежит в папке
/usr/share/backgrounds/cosmos/background-1.xml

Это простой xml файл с простыми инструкциями.
Его можно создать вручную, схема довольно проста.
Но можно использовать этот скрипт:

#!/usr/bin/perl

$staticDuration = "300.0";#1795.0
$transitionDuration = "5.0";#5.0

print <<"TBEGIN";
<background>
<starttime>
<year>2009</year>
<month>08</month>
<day>04</day>
<hour>00</hour>
<minute>00</minute>
<second>00</second>
</starttime>
TBEGIN

$pwd = `pwd`;
$pwd =~ s/[\n]//;
$isStart = 0;
opendir(DIR,".");
while ($name = readdir(DIR)) {
if($name =~ /jpg|png/){
if($isStart){
$pathLast = $pwd."/".$lastName;
$pathCurr = $pwd."/".$name;
print <<"Tname";
<static>
<duration>1795.0</duration>
<file>$pathLast</file>
</static>
<transition>
<duration>5.0</duration>
<from>$pathLast</from>
<to>$pathCurr</to>
</transition>
Tname
} else {
$pathFirst = $pwd."/".$name;
}
$lastName = $name;
$isStart = 1;
}
}
closedir(DIR);

print <<"TEND"
<static>
<duration>1795.0</duration>
<file>$pathCurr</file>
</static>
<transition>
<duration>5.0</duration>
<from>$pathCurr</from>
<to>$pathFirst</to>
</transition>
</background>
TEND


создайте текстовый файл gen.pl с этим кодом и положите в папку с фотографиями.
выполните команду:
perl gen.pl > background-2.xml


Теперь добавьте этот файл в "Параметры внешнего вида" - "Фон", вуаля.

вторник, мая 18, 2010

Плагин по regexp для gedit

Потребовался инструмент для мелкого редактирования текста с использованием regexp
То что может стандартный gedit уже не хватает, такие вещи как замена теста с использованием спец-символов таких как отступ(\t), конец строки(\n) решаются довольно просто, но дальше уже сложно.
Есть такой плагин в одном блоге описано как его поставить
Я повторюсь, его нужно скачать и распаковать в папку ~/.gnome2/gedit/plugins/
Создать если не существует.
Теперь можно использовать такие конструкции как поиск функции название которой вы точно не помните, например ищете Что_то_тамSave
function\s+.*Save.*

вторник, апреля 20, 2010

Настройка времени под linux

Самый простой способ:
sudo ntpdate 0.ru.pool.ntp.org

Список всех серверов:
0.ru.pool.ntp.org
1.ru.pool.ntp.org
2.ru.pool.ntp.org
3.ru.pool.ntp.org

Теперь по порядку:

1.Установить часовой пояс


sudo dpkg-reconfigure tzdata

2.Синхронизация


ntpdate 0.ru.pool.ntp.org

3.Настройка обновления


$ sudo bash
# echo "ntpdate 0.ru.pool.ntp.org" > /etc/cron.daily/ntpdate
# chmod 755 /etc/cron.daily/ntpdate

четверг, апреля 08, 2010

Простой способ вывода сообщения


public class MyActivity extends Activity
{
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Toast.makeText(
MyActivity.this,
"Ваше сообщение",
Toast.LENGTH_LONG
).show();
}
}

вторник, апреля 06, 2010

Как передать картинку в Activity через Intent

Короткий пример:

Uri imageUri = intent.getData();
mBitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), imageUri);
Intent intent = new Intent(TakePictureActivity.this, PreviewActivity.class);
intent.putExtra(EXTRA_BITMAP_DATA, mBitmap);
startActivityForResult(intent, REQUEST_PREVIEW);

среда, июля 15, 2009

Полезные заметки по symfony - 2

Если надо использовать функции из View в Controller, то надо вопользоваться sfLoader

class blogActions extends sfActions
{
public function preExecute(){
...
}
public function executeRedirect(sfWebRequest $request)
{
sfLoader::loadHelpers('Url');
$this->redirect(url_for('@archive_blog?id='.$this->currentBlog->getId(), 301);
}
}


Но лучше использовать внутренние средства, в symfony почти для каждого из составляющих MVC если дублирующие средства:

class blogActions extends sfActions
{
public function preExecute(){
...
}
public function executeRedirect(sfWebRequest $request)
{
sfLoader::loadHelpers('Url');
$this->redirect(
$this->getController()->genUrl('@archive_blog?id='.$this->currentBlog->getId()),
301
);
}
}


Исключение составляет вызов action из View, как например в ZendFramework, но в symfony похоже это не трубуется (прим. автора: по крайней мере в моей практике).

среда, июля 08, 2009

Как добавить в форму admin генератора ссылку

К примеру у вас есть backend (admin) и вам нужно поставить ссылку на какой нибудь ресурс.
Для этого нужно создать свой виджет, например, такой:



class sfWidgetFormHtmlLink extends sfWidgetForm
{

protected function configure($options = array(), $attributes = array())
{
$this->addOption('url', false);
$this->addOption('target', 'self'); // self, blank
$this->addOption('route', false);
$this->addOption('name', true);
}

public function render($name, $value = null, $attributes = array(), $errors = array())
{
if($this->getOption('route')){
return link_to(
$this->getOption('name'),
$this->getOption('route'),
array('target'=>'_'.$this->getOption('target'))
);
}

if($this->getOption('url')){
return "<a href='".$this->getOption('name').
"' target='_".$this->getOption('target')."'>".
$this->getOption('name')."</a>";
}

}
}


Теперь его просто использовать:

class SomeForm extends BaseSomeForm
{

public function configure()
{
$this->setWidget('external_link',new sfWidgetFormHtmlLink(array('url'=>'http://ya.ru','name'=>'Поискать')));
}
}


Меняя метод render можно создать свой виджет по выводу какого-либо html текста и т.д.

среда, июня 17, 2009

Полезные заметки по symfony - 1

Установка meta html данных:

class SomeObjectActions extends sfActions
{
public function executeShowObject(sfWebRequest $request){
...
$this->getResponse()->setTitle($this->object->getMetaTitle());
$this->getResponse()->addMeta('meta_keywords', $this->object->getMetaKeywords());
$this->getResponse()->addMeta('meta_description', $this->object->getMetaDescription());
}
}

Правильное использование sfWidgetFormTextareaTinyMCE

sfWidgetFormTextareaTinyMCE - это виджет, HTML WYSIWYG editor. Очень удобная вешь, но в блоге symfony очень скудно описан принцип работы, точнее в последней версии возникает ошибка:

You must pass a "class" attribute for a TinyMCE widget

Вот, как и какой класс надо указывать:

$this->setWidget('text', new sfWidgetFormTextareaTinyMCE(array(
'width' => 650,
'height' => 550,
'config' => 'theme_advanced_disable: "anchor,image,cleanup,help"',
)
,array(
'class' => 'tinyMCE',
)
));


в генераторе (если вы используете его в backend) generator.yml укажите class в атрибутах

config:
actions: ~
fields:
text: { label: 'Текст', attributes: { class: "tinyMCE" } }


еще обсуждение здесь

вторник, июня 16, 2009

Как заставить mysql5 использовать нужный вам default-character и collation

Для начала посмотрите что у вас есть


SHOW VARIABLES LIKE 'character_set%';
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)


По умолчанию Value=latin1

Теперь вы хотите чтобы все клиенты mysql сразу использовали нужную ва кодировку:
utf8,cp1251 или koi8r

Нужно добавить в файл my.cnf
/etc/mysql/my.cnf

Слудущие переменные:

[client]
default-character-set=utf8
[mysqld]
default-character-set=utf8
default-collation=utf8_general_ci
character-set-server=utf8
init-connect='SET NAMES utf8;'
collation-server=utf8_general_ci
[mysql]
default-character-set=utf8


После изменений перезагружайте сервер.
/etc/init.d/mysql restart

Если не работает еще раз проверьте что у вас происходит:

SHOW VARIABLES LIKE 'character_set%';


проверьте кодировку базы данных:

mysql> show create database yourdatabase;
+-------------+----------------------------------------------------------------------+
| Database | Create Database |
+-------------+----------------------------------------------------------------------+
| yourdatabase | CREATE DATABASE `yourdatabase` /*!40100 DEFAULT CHARACTER SET utf8 */ |
+-------------+----------------------------------------------------------------------+
1 row in set (0.00 sec)


Кодировка по умолчанию для создания таблиц наследуется.

Можно еще проще для ubuntu (10.04):
создать файл, например /etc/mysql/conf.d/mysqld_charset.cnf
с текстом:

[mysqld]
default-character-set=utf8
default-collation=utf8_general_ci
character-set-server=utf8
init-connect='SET NAMES utf8;'
collation-server=utf8_general_ci

[mysql]
default-character-set=utf8


и перезапустить mysql

пятница, мая 08, 2009

Полезные команды для web-разработчика

Искать любое упоминание чего-либо в проекте, исключая системные svn файлы:
grep -Rn 'mysql.php' ./ | grep -v svn

Перенести изменения из одного проекта в другой методом патча:
project1 $ svn diff > filename.patch
project2 $ patch -p0 -i ../project1/filename.patch

Собрать файлы в архив по определенному принципу, в данном случае измененные и добавленные файлы:
perl -e '$res = `svn stat|grep -E "^[AM]"`; $res =~ s/\+|^\w+\s*//gm; $res =~ s/\n/ /g; `tar cfz 1.tgz $res`;'


В буду дальнейшем буду пополнять, есть что то вспомню.

четверг, мая 07, 2009

Google I/O

Как многим разработчикам на Android или просто интерисующимся уже известно, что в 27-28 мая в Сан-франциско пройдет конференция посвященная разработке под Google.Android.
Будет затронуто очень много интересных тем, но самой интересной для меня будет тема посвященная разработке игр.
А именно Chris Pruett расскажет о  Writing Real-Time Games for Android, т.к. я сейчас сам разрабатываю игру, о которой скоро расскажу.
Он болжен будет рассказать о фреймворке, который он разрабатывает специально для разработчиков игр. К тому же расскажет о новых возможностях работы с OpenGLES появившихся в AndroidSDK1.5
Немного поискав я нашел (svn) что-то, что разрабатывает Chris, но не уверен, что это именно тот фреймворк, о котором шла речь.
Если кто "в теме" и нашел этот фреймворк, буду признателен, если скинете ссылку.

вторник, мая 05, 2009

Samsung I7500 будет первым телефоном на Android в России

Пресс-центр корпорации Samsung объявил о примерной дате выхода смартфона на базе Android: 3 квартал 2009 года.
Возникает много вопросов таких как:

  1. Будет ли Android.Market в России?
  2. Сколько будет стоить устройство?
  3. Почему Google позволяет появится первым устройством в России не свой аппарат G1 или G2?


Т.к. в России Samsung пользуется большой популярностью, то ответ на 3 вопрос выглядит логичным.
Если рассуждать дальше, то Google согласен пустить первым Samsung.
К тому же если посмотреть темпы распространения платформы по странам(в прошивке 1.5 уже доступна русская локаль), то скорее всего Android.Market в России в тому времени будет.
А стоить мне кажется он будет не дешевле 20 тыс. руб., чтобы составить конкуренцию iPhone.

суббота, марта 28, 2009

Segmentation fault в php5

Взгляните на этот код:

class A extends B
{
public function getA(){
if($this->getA()){
return $this->getA();
} else {
return $this->getB();
}
}
}

С первого взгляда все верно. Но выдает:
[Sat Mar 28 17:12:59 2009] [notice] child pid 11239 exit signal Segmentation fault (11)

Образуется цикл, тогда надо:

class A extends B
{
public function getA(){
if(parent::getA()){
return parent::getA();
} else {
return $this->getB();
}
}
}

среда, марта 25, 2009

Монтирование(mount) файловой системы по ssh

sudo apt-get install sshfs

sudo sshfs -o allow_other username@hostname.ru:/home/usernamedir /home/usermountdir

Можно создать файл mount.sh и сделать ярлык для запуска на него. Gnome легко определяет что надо ввести пароль для ssh и предлагает сделать это через GUI


вторник, марта 24, 2009

Необходимые компоненты для работы symfony в Ubuntu

Недавно переставил систему с ubuntu 8.10 x86 на ubuntu 9.04 x86_64 на свой рабочий acer aspire 5720G.
Пришлось настраивать систему заново, но так как я сейчас разрабатываю только под symfony. Настраивал работу системы как раз для симфони, поэтому можно рассматривать этот пост как Необходимые компоненты для работы symfony в Ubuntu.
Поставим apache и php5.

sudo apt-get install apache2 php5-mysql libapache2-mod-php5 php5-common mysql-server mysql-common mysql-client-5.0 php5-cli php5-xsl


Устанавливаем кодировку по умолчанию для mysql:

sudo mcedit /etc/mysql/my.cnf
или
sudo nano /etc/mysql/my.cnf

добавить в конец строчки:

default-character-set=utf8
character_set_client=utf8

вместо utf8 можно любую другую, например cp1251

Ставим svn. Если не используете, то можно пропустить.

apt-get install subversion

libapache2-svn ssl-cert libapache2-svn - опционально



Ставим symfony:
sudo mkdir -p /usr/share/php5/symfony-1.2/
sudo svn co http://svn.symfony-project.com/branches/1.2 /usr/share/php5/symfony-1.2/



<VirtualHost 127.0.0.1:80>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/symfony/web/
<Directory />
Options FollowSymLinks Indexes
AllowOverride All
</Directory>
ErrorLog /var/log/apache2/error.log
LogLevel warn
CustomLog /var/log/apache2/access.log combined
</VirtualHost>


Если проект начинаете с нуля:

wget http://www.symfony-project.org/get/sf_sandbox_1_2.tgz

tar xfz sf_sandbox_1_2.tgz
cp sf_sandbox
mv sf_sandbox/* /var/www/symfony/


Подключаем библиотеку symfony. В файле:
/var/www/symfony/config/ProjectConfiguration.class.php

меняем на:

require_once '/usr/share/php5/symfony-1.2/lib/autoload/sfCoreAutoload.class.php';


Проверяем
cp /var/www/symfony/
./symfony

если все без ошибок, то можно приступать к работе