2013-10-02 5 views
0
function partners($atts) { 
    extract(shortcode_atts(array( 
      'ids' => null, 
      'extra_options' => 'something' <----------------- in wordpress I can read this value using local $extra_options 
    ), $atts)); 
global $extra_options; <----------------- trying to change local var to global 

function print_partners_scripts() { 
    global $extra_options; <----------------- reading above variable 
    echo '<script type="text/javascript">' . "\n"; 
    echo 'jQuery(document).ready(function() {'. "\n"; 
    echo ' $(".partners-slider").bxSlider({ 
     slideWidth: 924, 
     auto: 0, 
     autoStart: 0, 
     moveSlides: 1, 
     minSlides: 3, 
     maxSlides: 8, 
     pager: false, 
     controls: false, 
     slideMargin: 5, 
     ' . $extra_options . ' <----------------- var is empty 
    });' . "\n"; 
    echo '});' . "\n"; 
    echo '</script>' . "\n"; 
} 
    add_action('wp_footer', 'print_partners_scripts'); 

    $ids = explode(',', $ids); 
    $output = '<div class="ps-wrap"><div class="partners-slider">'; 
    foreach($ids as $id) {  
    $img_attr = wp_get_attachment_image_src($id, 'full'); 
    $output .= '<div class="pslide"><img src="' . $img_attr[0] . '" /></div>';  
} 
    $output .= '</div></div>'; 

    return $output; 
} 

Привет, Я пытаюсь прочитать var $ extra_options внутри print_partners_scripts(). Переменная задана в функции partners(). Я пытался сделать его глобальным и просто использовать его в определенном месте, но я думаю, что я делаю что-то неправильно;)Вложенные функции, переменные - PHP

Заранее благодарен!

+0

ли определить вам функцию (print_partners_scripts) внутри другой функции (партнеры)? Зачем?! Вы действительно называете print_partners_scripts() где угодно? И вы сначала называете партнеров()? – OIS

+1

Использование глобальных переменных устарело. Вы должны либо передать информацию в функцию, либо использовать сеанс для хранения данных. –

+3

@JacobS У вас есть официальный источник этого иска? Глобалы обескуражены, но не устарели afaik. – OIS

ответ

1

Во-первых, PHP не поддерживает вложенные функции так, как вы их пытаетесь использовать.

Вы можете написать это:

function outer() { function inner() {} } 
outer(); 

Но все, что происходит в том, что, когда outer(); выполняется, функция inner() объявлена ​​как нормальной функции. Таким образом, код точно так же, как это:

function outer() {} 
function inner() {} 
outer(); 

Во-вторых, переменные в PHP (если не префиксом, с классом или имя объекта) всегда областью видимости текущей функции. Ключевое слово globalимпортирует ссылку глобальной переменной в область текущей функции; он не может использоваться для экспорта переменной, которая уже была определена.

Как правило, лучше всего использовать ключевое слово global в самом начале функции, чтобы импортировать все глобальные переменные, необходимые этой функции. Еще лучше, не используйте глобальные переменные, поскольку они приводят к «коду спагетти», который трудно понять и отладить.

Если вы объявляете переменную globalперед темextract работает, это будет работать, но я бы настоятельно рекомендуем использовать либо функцию.

function foo_with_too_much_magic() 
{ 
    // Import global variable. Very hard to track where this came from. 
    global $some_var; 
    // Let's assume this array comes from somewhere and isn't hard-coded 
    $some_array = array('some_var' => 'some_value'); 
    // Export variables from an array. This is like telling PHP to write different code each time it runs, with different variable names. 
    extract($some_array); 
} 
foo_with_too_much_magic(); 
var_dump($some_var); 

Вот версия выше без отчаявшихся функций:

function foo_with_no_magic() 
{ 
    // Let's assume this array comes from somewhere and isn't hard-coded 
    $some_array = array('some_var' => 'some_value'); 
    // You know which variable you want, so don't need the magic "export" 
    // Note that you don't have to call it $some_var 
    $some_var = $some_array['some_var']; 

    // Now you have the variable, you can manipulate it, pass it to another function, or return it 
    // In fact, you could also return $some_array['some_var'] directly, without the extra assignment 
    return $some_var; 
} 

// This variable name no longer needs to be the same as what was used in the foo_with_no_magic() function 
$some_var = foo_with_no_magic(); 
var_dump($some_var); 
+0

«Если вы объявите переменную global перед запуском экспорта, это будет работать, но я бы настоятельно советовал использовать любую функцию». Работал;) Спасибо за ваше время и ценные советы! – user2587741

+0

@ user2587741 Я добавил это к ответу, чтобы объяснить, почему он терпит неудачу, но ** пожалуйста ** не пишите такой код! Я добавил пример ответа о том, как писать код, не полагаясь на магию 'export' и' global'. – IMSoP

0

Вот пример того, чтобы поместить код в класс формат, который направление я бы FYI, это может быть полезно чтобы узнать немного больше практики ООП для PHP (http://php.net/manual/en/language.oop5.php):

#1) Get the data you wish to pass into your function. 
$data = "TEST"; 
get_partners($data); 

#2) Call your function. 
function get_partners($atts) { 
    //Extract using ($att) passed in from your call. 
    //The shortcode_atts function should be accessible by the file containing this function. 
    extract(shortcode_atts(array(
    'ids' => null, 
    'extra_options' => 'something' //in wordpress I can read this value using local $extra_options 
    ), $atts)); 
    //Create a new class element that will build your data for your and allow you to pass in your variable on the fly. 
    $p = new partners(); 
    $p->extra_options= $atts; //Pass the variable here. 
    $p->print_partners_scripts(); 
} 

#3) Define Class here. 
class partners { 
    var $extra_options; 

    public function print_partners_scripts() 
    { 
     $output = '<script type="text/javascript">' . "\n"; 
     $output .= 'jQuery(document).ready(function() {'. "\n"; 
     $output .= ' $(".partners-slider").bxSlider({ 
     slideWidth: 924, 
     auto: 0, 
     autoStart: 0, 
     moveSlides: 1, 
     minSlides: 3, 
     maxSlides: 8, 
     pager: false, 
     controls: false, 
     slideMargin: 5, 
     ' . $this->extra_options . ' 
     });' . "\n"; 
     $output .= '});' . "\n"; 
     $output .= '</script>' . "\n";    
     $output .= $this->additional_data(); 
     echo $output; 
    } 

    protected function additional_data() 
    { 
     add_action('wp_footer', 'print_partners_scripts'); 
     $ids; #Where is this defined? 
     $ids = explode(',', $ids); 
     $output = '<div class="ps-wrap"><div class="partners-slider">'; 

     foreach($ids as $id) 
     { 
      $img_attr = wp_get_attachment_image_src($id, 'full'); 
      $output .= '<div class="pslide"><img src="' . $img_attr[0] . '" /></div>'; 
     } 

     $output .= '</div></div>'; 
     return $output; 
    } 
} 
+1

ООП может быть полезен (хотя здесь может быть и слишком много), но это использует некоторые довольно плохие практики: функция 'get_partners' должна находиться внутри класса, возможно, как статическая функция; он по-прежнему использует 'extract' без необходимости; 'var' следует заменить на' public'; и имена функций обычно должны быть глаголами, поэтому 'Additional_data' должен быть' get_additional_data' или предпочтительно более подробным. О, и под «элементом класса», я думаю, вы имеете в виду «экземпляр». – IMSoP

+0

В этом примере функция get_partners не будет находиться внутри класса/экземпляра, так как это функция, которая создает класс/экземпляр. Хотя верно, что часть его логики может быть перемещена в сам класс/экземпляры. Вы предлагаете создать класс вне функции? – AJames

+0

Вот почему я предложил функцию * static *, чтобы вы могли запускать 'Partners :: get_partners ($ data)'. Или это может быть конструктор класса, так что вы будете запускать '$ partners = new Partners ($ data); $ Партнёры-> print_partners_scripts(); '. Скорее всего, в любом случае это будет внутри какой-то другой функции, содержащей все вызовы функций, необходимые на странице. – IMSoP

Смежные вопросы