Видимость функций при include

Norton

Новичок
Помогите решить следующую задачу:
Нужо сделать include 2 файлов з разными именами но одинаковыми функциями.

Пробовал вот эту конструкцию:

Файл test.php
PHP:
TestInclude::test(1);
TestInclude::test(2);


class TestInclude{

	public function test($i){
		include_once("testfunc".$i.".php");
	}
}
testfunc1.php
PHP:
<?php
function testfunc(){
	echo "TEST";
}
?>
testfunc2.php
PHP:
<?php
function testfunc(){
	echo "TEST";
}
?>
Понятное дело что при вызове test.php такая конструкция ругается:
PHP:
Fatal error: Cannot redeclare testfunc()
а мне надо чтобы она 2 раза вывела слово TEST.

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

Фанат

oncle terrible
Команда форума
fixxxer
я бы всё-таки сначала спросил - зачем ему это :)
 

Norton

Новичок
fixxxer
я бы всё-таки сначала спросил - зачем ему это :)
объясняю.

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

поэтому решил заинклудить файл этой программы (физический файл.. в примере testfunc1.php).
и вызвать функцию которая там определена специально для моих целей (activate_plugin, get_option, set_option и другие).

вот как то так:

PHP:
for($i=0;$i<$totaldomains;$i++){
include_once($wp_path."/wp-load.php");
include_once($wp_path."/wp-admin/includes/plugin.php");
$result=activate_plugin($plugin);
}
переменная $wp_path меняется в зависимости от пути куда установлен wordpress (для каждого домена свой путь на сервере).
поэтому пробовал в цикле создавать екземпляр класса (в первом посте описал структуру), и в нем уже делать include, считая что при unset эти все инклюды тоже пропадут. но вот не работает такой вариант. в доке понятно пишет
However, all functions and classes defined in the included file have the global scope
, но хочеться как то обойти это.


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

hell0w0rd

Продвинутый новичок
А почему не заключить в namespace код?
Если надо делать динамически - через временный файл?
 

keltanas

marty cats
Не уверен, на сколько это поможет в случае с wordpress, но в php 5.3+ возможен такой код:

PHP:
<?php
namespace ns1;

function hello() {
    print 'world1';
}

namespace ns2;

function hello() {
    print 'world2';
}

namespace ns;

\ns1\hello();
\ns2\hello();
Соответственно, функции с разными namespace можешь поместить в разные файлы а потом инклудить их.
 

Adelf

Administrator
Команда форума
А вызывать свой же скрипт из командной строки?
Для каждого плагина...
 

keltanas

marty cats
Кстати, возможно, тут стоит не городить огород, а воспользоваться одним из имеющихся подходов?
PHP:
NamingStrategy.php
<?php
interface NamingStrategy
{
    function createName($filename);
}
PHP:
ZipFileNamingStrategy.php
<?php
class ZipFileNamingStrategy implements NamingStrategy
{
    function createName($filename)
    {
        return "http://downloads.foo.bar/{$filename}.zip";
    }
}
PHP:
TarGzFileNamingStrategy.php
<?php
class TarGzFileNamingStrategy implements NamingStrategy
{
    function createName($filename)
    {
        return "http://downloads.foo.bar/{$filename}.tar.gz";
    }
}
PHP:
Test.php
<?php
class Test
{
    private $namingStrategy;
    function __construct(NamingStrategy $strategy)
    {
        $this->namingStrategy = $strategy;
    }
    function execute()
    {
        $url[] = $this->namingStrategy->createName("Calc101");
        $url[] = $this->namingStrategy->createName("Stat2000");
 
        return $url;
    }
} 
 
if (strstr($_SERVER["HTTP_USER_AGENT"], "Win"))
    $context = new Test(new ZipFileNamingStrategy());
else
    $context = new Test(new TarGzFileNamingStrategy());
 
$context->execute();
Ну и подцепить сюда код автозагрузки классов по одному из стандартов. Обычно, удобно пользоваться композером.
 

AmdY

Пью пиво
Команда форума
о. на днях отвечал на похожий вопрос
[5:37:00 PM] Alexandr : ну у меня есть два файла с функциями один глобальный один конкрено для определенного сайта, если я вызываю функцию на сайте, то нужно чтобы сразу искало функцию в файле конкретном для сайта, а потом если не найдет то уже в глобальном
[5:37:08 PM] Alexandr : те типа переопределение
[5:37:17 PM] Alexandr : только без классов
[5:38:04 PM] Slava Plisko: это для wordpress?
[5:38:10 PM] Alexandr : да
[5:39:20 PM] Slava Plisko: вобщем, в файле глобальном нужно все функции завернуть в
if (!function_exists( 'function_name' ) ) {
function function_name() {}
}
[5:39:46 PM] Slava Plisko: тогда первым инклудишь файл с функциями для сайта. а затем глобальный файл.
[5:40:58 PM] Alexandr : сча посмотрим
 

Norton

Новичок
Не уверен, на сколько это поможет в случае с wordpress, но в php 5.3+ возможен такой код:

PHP:
<?php
namespace ns1;

function hello() {
    print 'world1';
}

namespace ns2;

function hello() {
    print 'world2';
}

namespace ns;

\ns1\hello();
\ns2\hello();
Соответственно, функции с разными namespace можешь поместить в разные файлы а потом инклудить их.
нет, не работает так как мне нужно. тоже выдает redeclare error. фишка как раз в include.
PHP:
namespace ns1;

function hello($i) {
    include_once("testfunc".$i.".php");
}

namespace ns2;

function hello($i) {
    include_once("testfunc".$i.".php");
}

namespace ns;

\ns1\hello(1);
\ns2\hello(2);
я должен делать именно include нужных мне wordpress файлов в своем скрипте.

незнаю как ещё объяснить. вот такой принцип:
PHP:
for($i=0;$i<100;$i++){
include("/home/domain".$i.".com/wp-load.php");
activate_plugin();
}
в файле wp-load.php функции одинаковые, вот только пути к этому файлу разные в зависимости от домена.
я немогу сделав include для домена №1, заюзать эту функцию для других доменов. так как она сама инклюдит пол вордпресса с конфигами. поэтому нужно для каждого домена делать свой include.

А вызывать свой же скрипт из командной строки?
Для каждого плагина...
да, пока так и делаю, писал выше. через popen. вызов на каждый плагин, на каждую настройку и т.п.


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

и ещё совместно с xcache работать нормально не хочет. apache падает.
без xcache работает.


PHP:
$sandbox = new Runkit_Sandbox();
$sandbox->include_once("/testfunc1.php");
$sandbox->testfunc();
unset($sandbox);

$sandbox = new Runkit_Sandbox();
$sandbox->include_once("/testfunc2.php");
$sandbox->testfunc();
unset($sandbox);
содержимое testfunc1.php и testfunc2.php
PHP:
function testfunc(){
	echo "TEST";
}
Выводит 2 раза слово TEST.
Вот это и требовалось.
 

keltanas

marty cats
нет, не работает так как мне нужно. тоже выдает redeclare error. фишка как раз в include.
PHP:
namespace ns1;

function hello($i) {
    include_once("testfunc".$i.".php");
}

namespace ns2;

function hello($i) {
    include_once("testfunc".$i.".php");
}

namespace ns;

\ns1\hello(1);
\ns2\hello(2);
Соответственно, функции с разными namespace можешь поместить в разные файлы а потом инклудить их.
А ты эти функции все равно в текущем файле оставил, как и определения namespace.

Впрочем, если ты уже решил свою задачу, то не суть.
 
Сверху