Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Dublowanie nazwy funkcji własnej z funkcjami PHP
Forum PHP.pl > Forum > PHP
Brick
Już drugi raz mi się zdarzyło, że działająca strona nagle pada z komunikatem Cannot redeclare ....
Krótkie dochodzenie wyjaśnia, że na serwerze wgrano nową wersję PHP (lub jakiś jego dodatkowych bibliotek).
Problem polega na tym że wprowadzone nazwy nowych funkcji pokrywają się z istniejącymi moimi funkcjami!

Konkretny przykład: funkcja gethostname(), która pojawiła się w wersji PHP>=5.3.0
Kilka lat temu zdefiniowałem sobie taką funkcję, której używam w wielu skryptach i która działa inaczej niż ta dodana w PHP.
No i jest poważny problem. Nie będę przecież co chwilę zmieniał nazw swoich funkcji w miarę pojawiania się kolejnych wersji PHP. Zwłaszcza, że na wielu serwerach jest cała masa już wykonanych stron, które musiałbym przerabiać.

Czy ktoś się spotkał z takim problemem i ma sposób na to?

Moim zdaniem w takim wypadku PHP powinno wykonywać funkcję zdefiniowaną przez użytkownika i generować tylko powiadomienie (Notice) a nie Error. Czyli teoretycznie mógłbym zdefiniować swoją funkcję print() i ta oryginalna przestała by działać. W przypadku zdublowania nazw funkcji zdefiniowanych przez użytkownika Fatal Error powinien zostać. Nie wiem czy zostaje mi tylko pisać do twórców PHP żeby coś takiego uwzględnili czy jest jakieś inne rozwiązanie?
Jeżeli nie ma to ten problem będzie narastał w miarę rozwoju PHP.
nospor
Cytat
Nie wiem czy zostaje mi tylko pisać do twórców PHP żeby coś takiego uwzględnili czy jest jakieś inne rozwiązanie?
Nie ma. Musisz pisać do twórców, choć wątpie, by Cię posłuchali.

Od biedy możesz swoje funkcje definiować warunkowo czyli:
if (!function_exists(.....)) twojafunkcja.
No ale to sie nie sprawdzi, jesli twoje funkcję robią co innego niż funkcje php

Cytat
Jeżeli nie ma to ten problem będzie narastał w miarę rozwoju PHP.
Jakbyś pisał obiektowo, to byś nie miał takiego problemu.
Albo chociaż nadawa przedrostki swoim funkcją, to też nie będziesz miał problemu
IceManSpy
Myślę, że napisanie do twórców nic nie da, bo odpowiedzą Ci, żebyś sam sobie zmienił nazwę tej funkcji nawet na zasadzie znajdź i zasąp.

Poczytaj o namespace, które są odpowiedzią na Twój problem. Co i tak wziąże się z modyfikacją kodu i stoswania PHP w wersji 5.3 .
Crozin
Wina jest tylko i wyłącznie po stronie deweloperów PHP, którzy nie dbają należycie o wsteczną kompatybilność. Możesz im to napomknąć jeżeli zdecydujesz się napisać do nich. wink.gif

Co możesz zrobić? "Normalnie" niewiele, ale jest kilka obejść:
1. Zmień nazwę (dodaj prefiks bądź skorzystać z przestrzeni nazw) dla swojej funkcji i wszystkich jej wywołań we wszystkich aplikacjach.
2. Wyłączenie wbudowanej funkcji przez dyrektywę disable_functions w php.ini.
3. runkit_function_redefine.

Jednak dwa ostatnie rozwiązania należą do tych, których tak na prawdę nie powinno się stosować.
Brick
Dzięki za odpowiedzi.
Przynajmniej wiem na czym stoję i jakie mam opcje. Muszę pomału zacząć przerabiać swoją bibliotekę skryptów, albo nadając funkcjom prefix albo wstawić je do klasy. Chyba to drugie będzie lepsze bo przecież i prefix może kiedyś się powtórzyć.

Problem oczywiście jest z już wykonanymi wcześniej stronami ale na to nic nie poradzę.
Dzięki za podpowiedzi z runkit_function_redefine i disable_functions. To jest dobre, awaryjne rozwiązanie, które może się przydać żeby uratować stronę tymczasowo, zanim jej nie przerobię. Oczywiście na tych serwerach w których mogę php.ini zmodyfikować. Z tego co rozumiem runkit_function_redefine domysnie pozwala tylko zmodyfikować funkcje użytkownika, wewnętrzne można po zmianie w php.ini

Napiszę do ludzi z PHP, przecież ta zmiana którą sugeruję nie powinna być skomplikowana.Właściwie wymaga tylko zmiany ERROR na NOTICE w przypadku konfliktu funkcja_user<=>funkcja_wewnętrzna. Może pracują nad tym jacyś sensowni ludzie co_jest.gif
Przecież w miarę rozwoju PHP i pisanych przez ludzi skryptów będzie przybywało możliwych konfliktów i nawet prefixy mogą nie pomagać.
nospor
Cytat
Przecież w miarę rozwoju PHP i pisanych przez ludzi skryptów będzie przybywało możliwych konfliktów i nawet prefixy mogą nie pomagać.
Ale konflikt to jest poważna sprawa i nie można tego od tak byle NOTICEM zbyć. To że akurat tobie tak pasuje, nie znaczy że innym będzie pasowało. Ja sobie np. nie wyobrażam, by konfikt w nazwach puścić NOTICEM i skrypt dalej będzie chodził. Konflikt może wynikać z wielu różnych sytuacji a nie tylko z takich co ty tu opisałeś.
r4xz
najlepiej gdyby stosowali jeden zapis, np.
testTestTest,
test_test_test
lub testtesttest

wtedy można by dla swoich nazw funkcji stosować inną konwencję i wydaje mi się to jedynym słusznym rozwiązaniem.
Crozin
@r4xz: To nie ma tutaj nic wspólnego z problemem.
@Brick: Konflikt w nazwach nie powinien nawet pozwolić na uruchomienie skryptu, w ostateczności powinien zaprzestać jego wykonywania w momencie wystąpienia owego konfliktu. Takie problemy muszą być jawnie rozwiązane na poziomie kodu. A deweloperom możesz napisać żeby dupę ruszyli i całą bibliotekę standardową przepisali na taką wykorzystującą przestrzenie nazw - po czym zrobić to samo ze swoimi. wink.gif - i żeby jeszcze jasno określili konwencję nazewnictwa tych przestrzeni.
Brick
Cytat(Crozin @ 1.03.2012, 18:06:46 ) *
A deweloperom możesz napisać żeby dupę ruszyli i całą bibliotekę standardową przepisali na taką wykorzystującą przestrzenie nazw - po czym zrobić to samo ze swoimi. wink.gif - i żeby jeszcze jasno określili konwencję nazewnictwa tych przestrzeni.

Na to chyba nie będę liczył ;-) Bałagan już jest niezły w nazewnictwie funkcji, przykładowo rodzina string functions: chop, rtrim, ord, addslashes, a pozniej nagle cala rodzina str_pad, str_repeat, str_replace, i nagle nowa grupa strcomp, strlen, strpos. Fajnie by było jakby to wszystko przepisali z namespace ale chyba jest mała szansa.

Skoro mówicie żeby jednak przy konflikcie był Error to może chociaż w php.ini dało by się to przełączyć na Notice? Wprawdzie jest runkit_function_redefine ale wymaga podawania każdej funkcji z osobna.
Ale właściwie ile tych konfliktów może być... może przesadzam.
Niktoś
Stosowanie nazewnictwa polskiego i nie ma szans żeby jakieś funkcje sie dublowały w przyszłości między Tobą , a deweloperami PHP.Zawsze to jakieś rozwiązanie.
ano
Niktoś proszę Cię... już widywałem kody z getterami i setterami "dajX()", "ustawX(...)" i żałośnie to wyglądało. Polskie nazewnictwo to bardzo słaby pomysł wink.gif
i juz widze te zastępy funkcji
addslashes - dodajukośniki
str_replace - zastap_znaki
print - drukuj aaaaa

no jak to wygląda... biggrin.gif
Brick
Z polskimi nazwami jest tragedia niestety. Nie jestem zwolennikiem stosowania angielskiego wszędzie gdzie się tylko da ale do nazewnictwa funkcji, zmiennych czy tabel w bazie polski się nie nadaje. Powstają długie dziwaczne nazwy które ciężko odczytać. Też widzialem takie skrypty po polsku z funkcjami typu:
znajdz_najwieksza_wartosc,
sprawdz_poprawnosc_danych

albo ze zmiennymi:
$zwiekszona_wartosc
$polaczenie_z_baza

Ten nieszczęsny gethostname to będzie "okreslnazwehosta"?
A tez widziałem kiedyś tabelę w MySQL "urzytkownicy" biggrin.gif

Podsumowując: w każdym podręczniku do PHP powinno być wyraźnie napisane: tworząc swoje funkcje używaj przestrzeni nazw lub wstawiaj funkcje do klasy lub chociaż stosuj nietypowe przedrostki
W moim niestety nie było napisane, ale to było już dawno temu gdy php4 to była nowość ;-)
by_ikar
Cytat(Brick @ 2.03.2012, 08:34:50 ) *
Podsumowując: w każdym podręczniku do PHP powinno być wyraźnie napisane: tworząc swoje funkcje używaj przestrzeni nazw lub wstawiaj funkcje do klasy lub chociaż stosuj nietypowe przedrostki
W moim niestety nie było napisane, ale to było już dawno temu gdy php4 to była nowość ;-)


Powinno ale tak nie jest w większości przypadków. Głównie za sprawą przestarzałych informacji zawartych w tych podręcznikach, a podręczniki dalej są w obiegu. To nie jest matematyka, która potrzebuje gdzieniegdzie nawet paru dekad żeby coś się zmieniło. Tutaj te zmiany są wypuszczane często, wraz z nowymi wersjami php. Wczoraj wyszła finalna wersja php 5.4 i podręczników które jakoś sensownie traktują o zmianach w nowej wersji, to można szukać ze świecą..

IMO jak już masz php w wersji 5.3 to najsensowniejsze byłyby przestrzenie nazw. ja póki co, patrzę na przestrzenie nazw z przymrużeniem, z racji braku jakichś konwencji, przez co sporo osób nazywa sobie klasy jak im się podoba, i jest lekki śmietnik..
Niktoś
Stosowanie unikalnego nazewnictwa funkcj serwerowychi/tabel w bazie danych ,zmniejsza szanse na przeprowadzenie udanego ataku XSS/SQL INJECTION i nikt mi nie powie ,że tak nie jest.
Cytat
Niktoś proszę Cię... już widywałem kody z getterami i setterami "dajX()", "ustawX(...)" i żałośnie to wyglądało. Polskie nazewnictwo to bardzo słaby pomysł wink.gif
i juz widze te zastępy funkcji
addslashes - dodajukośniki
str_replace - zastap_znaki
print - drukuj aaaaa

Przecież ty mówisz o funkcjach wbudowanych ,proszę cię niby jakbyś miał zmienić addslashes na dodajukosnik??
Ps.W platformi NET ustrzegli się przed takimi wypadkami używając namespaców,niestety w PHP to jeszcze chyba magia.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.