Tribute to PHP - plugin do railsów, bez którego nie będziesz mógł żyć!
33 komentarze | Kategorie: Humor, Ruby, Ruby on Rails, Techblog | trackbackTagi: humor php plugin rails ruby
Myślę, że niewiele ryzykuję twierdząc, że większość piszących w Rubym tudzież Railsach dosyć intensywnie pisała wcześniej w PHP. Ja też nie jestem tu wyjątkiem. I chociaż uciekam od PHP jak najdalej i chyba tylko siłą można mnie zmusić by w tym pisać to są takie chwile, że tęskni się za pewnymi rozwiązaniami tego języka/środowiska.
Jednym z takich elementów PHP, za którym tęsknią bezwzględnie wszyscy są globalne zmienne $_GET, $_POST, $_COOKIE, $_SESSION. Otóż Railsy próbowały w jak najbardziej elegancki sposób rozwiązać te kwestie, jednak w tej kwestii na tle PHP wypadają słabo.
Sztucznie narzucony model MVC tylko zabiera nam swobodę programowania. Ile razy chciałeś sięgnąć w modelu to sesji, parametrów żądania czy też ciasteczek? A co z innymi miejscami takimi jak szablony czy też kod w katalogu RAILS_ROOT/lib/? Tak, tutaj Railsy są mocne ograniczone i tylko próbują to przed nami ukryć!
Na szczęście są sposoby by to obejść. Specjalnie na tę okazję napisałem dla Was plugin: Tribute to PHP. Wprowadza on wspomniane globalne zmienne. Możesz je używać dokładnie tak jak w PHP! Dodatkowo posiada chyba najlepsze co mogło się przydarzyć PHPowi (i nie wiem dlaczego zostało to wycofane z najnowszych wersji PHP - być może to jeden z tych złych posunięć, które poprowadzi PHP do śmierci:( ) a chodzi oczywiście o słynne (nie bez przyczyny) "register globals". W oryginale można było włączyć bądź wyłączyć tę opcję, w tym pluginie "register globals" jest włączone zawsze. Uważam, że wyłączanie tak przydatnej opcji mija się z celem.
Pozostaje mi tylko pokazanie małego przykładu użycia i umieszczenia kodu samego pluginu. Zachęcam wszystkich do pisania własnych propozycji co do rozwoju pluginu. Myślę, że Railsy w połączeniu z tymi najlepszymi cechami PHP mogą być jeszcze lepsze!
class User < ActiveRecord::Base
def self.authenticate
return $_POST['login'] == "radarek"
end
end
class HelloController < ApplicationController
def index
if request.post?
render :layout => true, :inline => %Q{
Twoj imie to: #{$imie}
}
else
render :layout => true, :inline => %Q{
<form method="post">
Podaj imie: <input type="text" name="imie" />
<input type="submit" value="Ok" />
</form>
}
end
end
def login_form
render :layout => true, :inline => %Q{
<form method="post" action="login">
Podaj imie: <input type="text" name="login" />
<input type="submit" value="Ok" />
</form>
}
end
def login
if User.authenticate
render :text => "OK"
else
render :text => "Sorry..."
end
end
def guess
if $_GET["a"] == "1" && $_GET["b"] == "2"
$_SESSION["c"] = "3"
redirect_to :action => "guessed"
return
end
render :text => "guess"
end
def guessed
render :text => $_SESSION["c"]
end
end
To tylko kilka prostych przykładów. Pamiętaj o tym, że dostęp do tych zmiennych masz z każdego miejsca aplikacji! Otwiera to nowe możliwości i tylko Twoja wyobraźnia jest ich ograniczeniem. Czekam na Wasze opinie i jestem ciekaw ilu z Was oprze się pokusie użycia tego w produkcji!
Na koniec kod pluginu
Kod pliku init.rb
TributeToPhp.setup_global_variables
ActionController::Base.send(:include, TributeToPhp::Controller)
Kod pliku lib/tribute_to_php.rb
# TributeToPhp
module TributeToPhp
module Controller
def self.included(base)
base.alias_method_chain :perform_action, :extract_php_params
end
protected
def perform_action_with_extract_php_params(*args, &block)
$_GET.params = self.request.query_parameters
$_POST.params = self.request.request_parameters
$_COOKIE.params = self.request.cookies
$_SESSION.params = self.session
# register globals
registered_globals = []
[$_GET, $_POST, $_COOKIE, $_SESSION.data].each do |superglobal|
superglobal.each do |name, value|
if name =~ /^[a-zA-Z_][a-zA-Z_0-9]*$/
registered_globals << name
eval("$#{name} = #{value.inspect}")
end
end
end
begin
perform_action_without_extract_php_params(*args, &block)
ensure
registered_globals.each do |variable_name|
eval("$#{variable_name} = nil")
end
end
end
end # Controller
class HashParamsProxy
attr_accessor :params
def initialize(params = nil)
@params = params
end
def [](*args)
self.params.send(:[], *args) if self.params
end
def []=(*args)
self.params.send(:[]=, *args) if self.params
end
def method_missing(method_name, *args, &block)
if self.params && self.params.respond_to?(method_name)
return self.params.send(method_name, *args, &block)
else
return super(method_name, *args, &block)
end
end
end # HashParamsProxy
def self.setup_global_variables
$_GET = TributeToPhp::HashParamsProxy.new
$_POST = TributeToPhp::HashParamsProxy.new
$_COOKIE = TributeToPhp::HashParamsProxy.new
$_SESSION = TributeToPhp::HashParamsProxy.new
end
end
Żart? Register globals doprowadziło do tylu błędów, że jak widzę kod z ich użyciem, to mnie mdli…
ZOMG! Jesteś chyba jedyną osobą, która uważa że RG jest dobre, a wynika to pewnie z: – byciem omega-programistą, który przewiduje każdy wypadek wykorzystania skryptu i definiuje każdą zmienną przed jej użyciem – nie znajomości zagrożeń z tym związanych – skończonego kretynizmu – byciem dupą a nie programistą ;-)
LOL
666/10 za pomysł i realizację :D
Globale pehapowe to pikuś, wykorzystanie inline’owych renderów niszczy w tym tekście najbardziej. :D
Brawo dla wszystkich, którzy nie zrozumieli dowcipu Radarka ;)
Jeżeli defacto jest to dowcip, to wyjątkowo nie udany – nie każdy musi znać RoR. Tak samo mogę zaraz napisać dowcip w Brainfuck’u i ciekawe, kto zrozumie? ;>
Targetem tej notki są programiści RoR, co widać po – tytule – wstępie – tagach – tekście – fragmentach kodu
Po prostu nie złapałeś dowcipu i tyle, nie ma co się wykręcać z braku lotności :P
Co za perfidna prowokacja. ;-)
jak prowokacja – to dobra :D
jak rzeczywista potrzeba – to o japierdole
Właśnie dlatego pytałem, czy to żart :>
Nie myślałem, że ktoś weźmie to na poważnie :D. Dobrze chociaż, że Ci co dobrze odgadli moje intencje byli tego w 100% pewni.
Dobre żarty zwykle wymagają pewnej wiedzy. Mój blog jest dedykowany Rubiemu, a póki co po ludziach piszących w tym języku mogę się spodziewać, że znają Railsy.
Akurat nie piszę w Ruby, a wpis ukazał się na jogger.pl a nie ruby.pl więc nie zakładajmy, że każdy kto odwiedza Twój blog wie o czym jest ;-)
Oczywiście nikomu nie zabraniam, a właściwie zachęcam do śledzenia mojego bloga :). Każdy blog ma swoją tematykę, wystarczy prześledzić kilka postów z głównej strony joggera. Czyżby zachęciło Cię słowo „PHP” w tytule do przeczytania wpisu?:P
Jak programistę PHP, tak właśnie się stało ;-)
Nie ukrywam, że PHP nie jest w moich oczak idealnym językiem, ma wiele wad ale nadaje się do tego, czego od niego oczekuję.
Ruby liznąłem parę razy – ma fajną składnie, ale jakoś do mnie RoR nie przemawia ;-)
@btm i wiesz co Ci powiem? Pozostań przy PHP póki co. Serio. Dopóki jest to dla Ciebie wystarczające narzędzie i nie denerwuje Cię to co denerwowało nas wszystkich* w PHP to nie ma sensu na siłę pisać w Rubym/Rails. Railsy są super, ale to nie jest złoty środek na wszystko.
Czasem też trzeba tak bardzo pomęczyć dany język, aż zacznie nas coś w nim denerwować (tak miałem z PHP). U mnie to się przerodziło we frustrację stąd przejście na Ruby. I nie dość, że Ruby to co denerwowało mnie w PHP ma zrobione porządnie (przede wszystki OOP) to jeszcze doszło do tego masę wspaniałych rzeczy (np. metaprogramowanie, DSL).
Aczkolwiek tak jak wspomniałem, gdybym nie posiadał pewnej wiedzy to nie doceniłbym tego w Rubym. To tak jakbyś komuś chciał pokazać, że MVC jest lepsze niż 1 plik php w którym masz html + php + sql, osobie, która w ogóle nie programowała. Trzeba wpierw poczuć na własnej skórze czym to się kończy :).
*nas wszystkich – czyli ludzi piszących w Rubym, którzy wcześniej pisali w PHP (myślę, że około 95% obecnych programistów Rubiego)
Ale widzisz, ja (aktualnie) nie mam ambicji pisać większych aplikacji, bo wiem ile przy tym jest rypania – wiem ile jest rypania już przy średnich aplikacjach.
Nie chcę zaczynać dyskusji o przewadze proszku A nad proszkiem B – jak mówiłem, w PHP jest wiele rzeczy które mnie denerwują (np. nie ma możliwości przeładowania większości funkcji, że o przeładowaniu operatorów nie wspomnę) – ale jako osoba koncentrująca się raczej na tworzeniu stron, sklepów i średni zaawansowanych portali a przy tym w PHP orientująca się – powiem nie skromnie – doskonale + posiadająca pewien warsztat (swój własny CMS, swój własny framework) etc. nie widzę aktualnie potrzeby zmiany platformy.
Dodatkowo, wierzę, że rozwój języka zmierzać będzie w dobrym kierunku.
A dodatkowo, jak mam z tego kasę na którą nie mam podstaw narzekać (powiem tylko, że ostatnio pewna firma oferowała mi prawie 4.500 netto na miesiąc, ale im odmówiłem i zostałem tam gdzie jestem) ;-)
Dlatego właśnie napisałem: Ruby nie jest złotym środkiem, nie trafi do każdego i nie ma potrzeby bo wszyscy na niego przechodzili :). To nie są żadne podchody, ale życiowe i pragmatyczne podejście. Jeśli ktoś zainwestował sporo czasu w swoje umiejętności (np. programowania PHP, frameworki, biblioteki) to przejście na inną technologię nigdy nie obędzie się bez ogromnego wysiłku i sporej ilości czasu.
ps. Ruby też ma wady, swoje kruczki i „quirks”... :)
Trollujesz :)
Jak to trolluje?:>
Kurde, Radarek, aleś nawymyślał... :D sam się nabrałem, dopiero po paru akapitach zacząłem mieć wątpliwości, a przy widokach inline sprawa się wyjaśniła ;)
Psi, zobaczysz, jeszcze będą tacy co będą mi dziękować za ten plugin! :P
BTM, prosta sprawa – do odrzucenia pehapa trzeba… jak by to ująć, żeby nie urazić pehapowców (sam jestem, co prawda byłym, ale zawsze)... dojrzeć. Zrobić w tym języku jakiś poważniejszy sajt „from scratch” albo chociaż uczestniczyć w tworzeniu lub utrzymaniu takiego.
To główny powód, dla którego rubiowcy (railsowcy konkretnie) nie ewangelizują „na siłę” pehapowców – dojrzeją, sfrustrują się, po drodze poznają zaawansowane techniki i narzędzia i będą bardzo dobrym i podatnym materiałem na nauczenie RoR :)
E tam, wcale nie trzeba dojrzewać. Czasem wystarczy poznać inny język i już :). Ja odrzuciłem PHP od kiedy poznałem Pythona i zacząłem interesować się Django, oraz GAE . Co prawda programowaniem zajmuje się totalnie hobbystycznie (nie wiążę z tym swojej przyszłości), ale naprawdę poznanie Pythona wystarczyło do stwierdzenia, że jeżeli musiał nie będę to do PHP nie wrócę.
Na pewno się tacy znajdą.
Nie no, bądźmy poważni. Jak ktoś użyje tego na serio to ma lekko niepoukładane w głowie. Nie wierzę, że jest ktoś w stanie przebrnąć przez railsy i widzieć sens użycia tego :).
Szanuje cie Radarek ale to są spore Jaja :) JA nie pisałem nigdy w PHP ale jakbym zobaczyl ten plugin to bym sie wystraszył i zapytał ludzi w projekcie czy komuś przez przypadek nie zlasował sie mózg.
Serio, serio
Moje ostatnie doświadczenia z wyrobnikami od Javy, którzy zostali zmuszeni do pisania w Rails (w sensie – klienci na nich to wymogli) jest takie, że z chęcią po coś takiego by sięgnęli.
A tak na poważnie – niestety, ale są miejsca gdzie brak dostępu do sesji HTTP uniemożliwia pisanie aplikacji fat model/skinny controller (dopuszczam możliwość, że czegoś nie wiem ;) ). Chodzi na przykład o Facebook API – obiekty do komunikacji z FB muszą mieć dostęp do sesji, więc w modelu nie użyjesz ich, a to oznacza że cała logika korzystająca z calli do FB API musi pozostać w kontrolerze.
@JO: no bo to są po prostu jaja. Taki przerywnik. Przy okazji można czegoś się nauczyć (ktoś analizował kod pluginu?). Chyba nie wziąłeś tego serio?;)
Nie no :D niema czasu na takie marnotrastow jak analiza kodu plugina :)
@JO: aha, Ty jesteś z tych co wezmą, skopiują i użyją?:D (żart)
@NetManiac: niech zgadnę, Ci javowcy piszą kod Javy w Rubym?;) (http://radarek.jogger.pl/2008/04/14/you-can-write-fortran-in-any-language/ ).
To, że są miejsca, w których nie ma dostępu do żądania http czy też sesji to zbawienie. Inaczej kończysz na zapytaniach SQL wprost z szablonu.
A co do FaceBook API – nie używałem ale pamiętam, że chyba opisywałeś ten problem na blogu. Nie ma tu innej siły jak po prostu przekazywać explicite parametr do metody.
:D Tak ! masz mnie :> Od dziś używam tylko PHP_RAILS i zaraz zaczne rozkminiac jego kod :>
akurat prowokacja… uratuwał swoją dupę w badziewny sposób…. „obłsuga parametrów żądań w modelu” .. mega kurwa lol
Mr @ja: jeśli chcesz podyskutować to nie używaj brzydkich słów (te zostaw na inne okazje) i podpisz się. Mogę zrozumieć, że nie załapałeś żartu, ale takiego zachowania nie bardzo. Pozdro.
Gdybym znał RoR, gdybym znał PHP to bym może zaoszczędził życia na analizie tego kodu ;P a tak … zabrakło mi definicji metody perform_action_without_extract_php_params
i już wiedziałem, że coś tu śmierdzi :/
ehhh życie :D
To po części magia rails.
to inny zapis
Tutaj można doczytać: http://weblog.rubyonrails.org/2006/4/26/new-in-rails-module-alias_method_chain i google: alias_method_chain .