Hilfe für eine wiederverwendbare PHP-Funktion zu schaffen, die ‚dynamisch‘ andere Funktionen aufrufen wird

StackOverflow https://stackoverflow.com/questions/2063691

Frage

Dies ist mein erstes Mal, wenn ich versuche, etwas ernsthaft mit relationalen db in MySQL und eine Art von CMS in PHP mit CodeIgniter erstellt zu machen.
Ich kam zu dem Teil, wo ich einige Daten in wenigen many-to-many verknüpften Tabellen einfügen muß.
In meinem Code funktioniert alles einwandfrei (gut, mit nur wenigen Minuten der Prüfung), aber ich brauche Hilfe bei wiederverwendbarer Funktion zu schaffen, die mir sehr helfen wird alle Beziehungen in meinen Tabellen ...

zu machen

ich Kommentar alles versucht, in meinem Code, so dass alle Erklärungen in dort ...

sind
<?php
function add(){

 // This is what user posted in form.
 // There are two input fields:
 // name is always only one record
 // country can be a single record or array separated with " | " characters
 // I use CodeIgniter's $this->input->post instead of $_POST[]
 $name = $this->input->post('name');
 $countries = $this->input->post('country');

 // Inserting data to first table
 $data = array('firstName' => htmlentities($name)); // preparing array for inserting
 $insert_name = $this->db->insert('names', $data); // inserting with CodeIgniter's help
 $last_inserted_ID = $this->db->insert_id(); // getting last inserted ID

 // Inserting data to second table

 // Formatting of posted string of countries
 // Users can post strings similar to this:
 // "Austria"
 // "Austria |"
 // "Austria | "
 // "Austria | Australia"
 // "Austria | Australia |"
 // "Austria | Australia | "
 // and similar variations
 // What I need here is clear array with country names
 $separator = strpos($countries,"|"); // check for "|" character
 if ($separator === FALSE){ // if there is no "|" character in string
  $countries_array[] = $countries; // array is only one value (only one country)
 } else {
  $countries_array = explode(" | ", $countries); // explode my array
  if (end($countries_array) == ""){ // if last item in array is ""
   array_pop($countries_array); // eliminate last (empty) item
  }
 }

 // Now, this is the part I think I will use lots of times.
 // I would like to make this a separate function so I could use it in many places :)
 // I would pass to that function few values and I would use one of them
 // to call different functions in this same class.
 // I guess I should pass data ($countries_array) and function names I wish to call?????? This is problematic part for my brain :))
 // Check the comments below...
 for ($i = 0; $i < sizeof($countries_array); $i++){
  $insertIDS = array(); // this will be an array of IDs of all countries
  $tempdata = $this->get_countries($countries_array[$i]); // query which looks if there is a country with specific name
                // Right here, instead of calling $this->get_countries
                // I would like to call different functions, for example
                // $this->get_links($links_array[$i])
                // or $this->get_categories($categories_array[$i])
                // etc.
  if(sizeof($tempdata) != 0){ // so, if a record already exists
   foreach ($tempdata as $k => $v){
    $insertIDS[] = $k; // insert those IDs in our array
   }
  } else { // and if a record does not exist in db
   $this->add_country($countries_array[$i]); // add it as a new record...
               // This is also one of the places where I would call different functions
               // for example $this->add_link($links_array[$i])
               // or $this->add_categories($categories_array[$i])
               // etc.
   $insertIDS[] = $this->db->insert_id(); // ...get its ID and add it to array
  }

  // Finally, insert all IDs into junction table!
  foreach ($insertIDS as $idKey => $idValue){
   $this->add_names_countries($last_inserted_ID, $idValue); // Another place for calling different functions
                  // example $this->add_names_links($last_inserted_ID, $idValue)
                  // etc.
  }
 }

}
?>

Nun, jetzt an diesem Code suchen, ich sehe, dass ich auch, dass die Formatierung Teil in dieser Funktion setzen könnte, aber das ist nicht so sehr wichtig, gerade jetzt ...

Danke sehr, sehr viel für jede Hilfe mit diesem !!

War es hilfreich?

Lösung

Der bevorzugte Weg, dies zu tun, ist die Verwendung eines Table Data Gateway . Statt

$this->db->insert('countries', $data);

Sie erstellen Klassen für jede Tabelle in der Datenbank. Jede Tabelle kapselt CRUD Logik in die Klasse, z.

class Countries
{
    $protected $_db;

    public function __construct($db)
    {
        $this->_db = $db;
    }

    public function save(array $countries)
    {
        $this->db->insert('countries', $countries);
    }

    // ... other methods
}

Darüber hinaus schlage ich verwenden Transaktionen für diese Art von Arbeit weil alle das Zeug wahrscheinlich wollen keine Daten eingefügt werden zusammen gehört und Sie, wenn eine der Abfragen fehlschlägt. Ich weiß nicht, wie CodeIgnitor Transaktionen abwickelt, aber im Grunde, sollten Sie es auf diese Weise tun, dann:

$this->db->startTransaction();          // like try/catch for databases
$countries = new Countries($this->db);
$countries->save($countryData);
$links = new Links($this->db);
$links->save($linkData);
// ...
if($this->db->commit() === false) {     // returns true when no errors occured
    $this->db->rollback();              // undos in case something went wrong
}

Während diese nicht beantwortet Ihre Frage, wie dynamisch eine Funktion aufzurufen ( call_user_func() könnte dies tun), tun es, wie oben angedeutet macht den Code viel besser verwaltbar.

Ihre Frage ist ein wenig vage zu, wenn Sie wollen, dass alle Funktionen in einer Folge laufen oder einfach nur auszutauschen, je nachdem, was der Benutzer übermittelt. Für den ersten Fall, verwenden Sie die Transaktion Ansatz. Für den zweiten Fall würden Sie einfach die entsprechende Klasse instanziiert und die Save-Methode aufrufen.

Andere Tipps

Nicht ganz sicher Ihre Anforderungen, aber ich denke, Sie nach call_user_func sein könnten:

function process($countries) {
// do stuff
}

$function_name = 'process';

call_user_func($function_name, $countries);

Auf diese Weise können Sie dynamisch eine Funktion zuweisen, basierend auf, sagen wir, die Liste der Länder.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top