49 votes

Stratégie de développement de versions de noms de code PHP identiques ou non.

Je suis le maintien de la bibliothèque écrite en PHP 5.2 et j'aimerais créer PHP 5.3-des espaces de version de celui-ci. Cependant, je voudrais aussi garder les espaces de la version à jour jusqu'à la version PHP 5.3 devient tellement vieux, que même Debian stable navires ;)

J'ai plutôt un code propre, environ 80 classes suivantes, Project_Directory_Filename schéma d'affectation de noms (je voudrais les changer en \Project\Directory\Filename bien sûr) et à seulement quelques fonctions et des constantes (également préfixé par le nom du projet).

La Question est: quelle est la meilleure façon de développer des espaces et non des espaces de versions en parallèle?

  • Devrais-je créer fourche dans le dépôt et garder les modifications de la fusion entre les branches? Existe-il des cas où la barre oblique inversée saupoudré code devient difficile de fusion?

  • Devrais-je écrire un script qui convertit version 5.2 à 5.3 ou vice-versa? Dois-je utiliser PHP générateur de jetons? sed? Préprocesseur C?

  • Est-il une meilleure façon d'utiliser les espaces de noms lorsqu'ils sont disponibles et de garder une compatibilité ascendante avec les anciennes PHP?


Mise à jour: a Décidé, contre l'utilisation des espaces de noms après tout.

9voto

Evert Points 17625

Je ne pense pas que le prétraitement de l'5.3 code c'est une excellente idée. Si votre code est fonctionnellement identique dans les deux PHP 5.2 et 5.3, à l'exception de l'utilisation des espaces de noms, au lieu de souligner séparées par des préfixes, pourquoi utiliser des espaces de noms à tous? Dans ce cas, il me semble que vous voulez utiliser des espaces de noms, pour le plaisir d'utiliser les espaces de noms..

Je ne pense que vous allez trouver ce que vous migrer vers les espaces de noms, vous allez commencer à "penser un peu différemment" sur l'organisation de votre code.

Pour cette raison, je suis fortement d'accord avec votre première solution. Créer une fourchette et faire des backports de fonctionnalités et corrections de bugs.

Bonne chance!

7voto

NikiC Points 47270

C'est une suite de ma réponse précédente:

L'espace de noms du code de simulation obtenu tout à fait stable. J'ai déjà pouvez obtenir symfony2 de travail (certains problèmes encore, mais au fond). Si il y a encore des choses manquantes comme la variable d'espace de noms de résolution pour tous les cas hormis new $class.

Maintenant, j'ai écrit un script qui va se répéter de manière récursive par le biais d'un répertoire et tous les fichiers: http://github.com/nikic/prephp/blob/master/prephp/namespacePortR.php


Les Instructions D'Utilisation

Exigences pour votre code fonctionne

Vos noms de classe ne doit pas contenir de l' _ de caractère. S'ils le font, les noms de classe pourrait obtenir ambigu lors de la conversion.

Votre code ne doit pas redeclare toutes les fonctions globales ou des constantes à l'intérieur d'un espace de noms. Ainsi, il est veillé à ce que tout votre code peut être résolu au moment de la compilation.

Fondamentalement, ce sont les seules restrictions qui s'appliquent à votre code. Si je devrais noter que dans une configuration par défaut de la namespacePortR ne résoudra pas les choses comme $className = 'Some\\NS\\Class'; new $className, car cela nécessiterait l'insertion de code supplémentaire. C'est mieux que cela soit corrigé plus tard (soit manuellement ou en utilisant un système automatisé de système de brassage.)

Configuration

Comme nous l'avons fait l'hypothèse qu'aucune fonction globale ou constante est redéclarée dans un espace de noms, vous devez définir l' assumeGlobal constante de classe dans l' espace de noms de l'auditeur. Dans le même jeu de fichiers de l' SEPARATOR de la constante d' _.

Dans le namespacePortR changer le bloc de configuration pour répondre à vos besoins.


PS: Le script peut être fourni un ?skip=int option. Cela dit il d'ignorer le premier int fichiers. Vous ne devriez pas en avoir besoin, si vous avez réglé le mode remplacement intelligent.

1voto

porneL Points 42805

Voici ce que j'ai trouvé:

De le faire avec des expressions régulières est un cauchemar. Vous pouvez obtenir la plupart de le faire avec juste quelques expressions simples, mais ensuite, en cas de bord sont d'un tueur. J'ai fini avec les horribles, fragile gâchis qu'à peine fonctionne avec une base de code.

C'est faisable avec built-in générateur de jetons et récursive simple descente de l'analyseur qui traite uniquement le sous-ensemble simplifié de la langue.

J'ai fini avec les moches conception (analyseur et le transformateur dans un la plupart du temps simplement de changer ou de re-émission de jetons), car il semble trop de travail pour construire utile de l'arbre syntaxique avec un espace maintenu (je voulais résultant de code lisible par un humain).

Je voulais essayer phc pour le présent, mais n'a pas pu convaincre son configure que j'ai bâtie version de bibliothèque Boost.

Je n'ai pas essayé ANTLR pour cela, mais il est probablement le meilleur outil pour ce genre de tâches.

1voto

NikiC Points 47270

Je suis en train de travailler sur un projet qui émule PHP 5.3 sur PHP 5.2: prephp. Il comprend l'espace de noms de soutien (pas encore terminée.)

Maintenant, hors de l'expérience de l'écriture, ce n'est un problème de l'ambiguïté dans l'espace de noms résolution: non Qualifiés des appels de fonctions et de constantes recherches ont un repli à l'espace de noms global. Donc, vous pouvez convertir votre code automatiquement uniquement si vous soit pleinement qualifié ou qualifié tous vos appels de fonction/constante de recherches ou si vous n'avez pas de redéfinir une fonction constante dans un espace de noms avec le même nom en tant que PHP en fonction.

Si vous respecter strictement cette pratique (celui que vous choisissez), il serait assez facile de convertir votre code. Il serait un sous-ensemble du code pour l'émulation des espaces de noms dans prephp. Si vous avez besoin d'aide avec la mise en œuvre, n'hésitez pas à me demander, je serais intéressé ;)

PS: L'espace de noms d'émulation de code de prephp n'est pas encore complet et peut être buggy. Mais il peut vous donner quelques idées.

1voto

Theodore R. Smith Points 4410

Voici la meilleure réponse que je pense que vous allez être en mesure de trouver:

Étape 1: Créez un répertoire appelé 5.3 pour chaque répertoire w/ php5.3 le code et le coller toutes 5.3-code spécifique.

Étape 2: Prenez une classe que vous voulez placer dans un espace de noms et le faire dans 5.3/WebPage/Consolidator.inc.php:

namespace WebPage;
require_once 'WebPageConsolidator.inc.php';

class Consolidator extends \WebpageConsolidator
{
    public function __constructor()
    {
        echo "PHP 5.3 constructor.\n";

        parent::__constructor();
    }
}

Étape 3: Utiliser une stratégie de fonction pour utiliser le nouveau code PHP 5.3. Placer dans des PHP5.3 findclass.inc.php:

// Copyright 2010-08-10 Theodore R. Smith <phpexperts.pro>
// License: BSD License
function findProperClass($className)
{
    $namespaces = array('WebPage');

    $namespaceChar = '';
    if (PHP_VERSION_ID >= 50300)
    {
        // Search with Namespaces
        foreach ($namespaces as $namespace)
        {
            $className = "$namespace\\$className";
            if (class_exists($className))
            {
                return $className;
            }
        }

        $namespaceChar = "\\";
    }

    // It wasn't found in the namespaces (or we're using 5.2), let's search global namespace:
    foreach ($namespaces as $namespace)
    {
        $className = "$namespaceChar$namespace$className";
        if (class_exists($className))
        {
            return $className;
        }
    }

    throw new RuntimeException("Could not load find a suitable class named $className.");
}

Étape 4: Réécrire votre code ressemble à ceci:

<?php
require 'findclass.inc.php';

$includePrefix = '';
if (PHP_VERSION_ID >= 50300)
{
        $includePrefix = '5.3/';
}

require_once $includePrefix . 'WebPageConsolidator.inc.php';

$className = findProperClass('Consolidator');
$consolidator = new $className;

// PHP 5.2 output: PHP 5.2 constructor.
// PHP 5.3 output: PHP 5.3 constructor. PHP 5.2 constructor.

Qui va travailler pour vous. C'est un cludge en terme de performance, mais juste un peu, et vont disparaître lorsque vous décidez d'arrêter de soutenir 5.3.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X