新生活遺産プロジェクト

ハブには、うまくやる方法についての記事がたくさんあります。 それをしない方法についての記事がたくさんあります。

しかし、もしあなたが仕事をし、ビジネスにお金をもたらすプロジェクトを持っているのに、プログラマーからは、その中の何かを理解することはほとんどできないとしたらどうでしょう。 各変更はあなた自身のリスクで行われ、ロシアンルーレットをプレイするリスクがあります。



まあ、1年か2年で新しいプロジェクトをゼロから準備するとき(そのような経験がありました)。 しかし、古いエンジンが完全に曲がっている間に、オーナーが最初から何かを並行して行うという事実に投資する準備ができていない場合。 すべてを新しい方法で書くことについて話そうとする試みも、即座に拒否されます。 しかし、小さなステップで試して、新しいエンジンを作成することができます。これにより、プロジェクトで次第に大きな役割を担うようになります。 実際、このような代替品を作成した経験についてお話ししたいと思います。



与えられた



コンサートチケット、PHPと筋肉を販売するサイト、コードは古く、小さな論理的分離(私の好みでは、bitrixより少し良い)、テンプレート、ビジネスロジック、データベースへの直接クエリを1つの方法で直接持っています。 2,000行以上で最も使用されるクラス。 一般的に、すべてが私たちの好きなものです。



私たちはどこに移動していますか? Symphonyは、これが私たちの環境で最も人気のあるフレームワークであるため、プロジェクトを作成するのに1年以上を費やした多くの人々がいます。 また、シンフォニーは現在、多くのプロジェクトで使用され、優れたドキュメントがあり、多くの新しいphpチップを使用しています。 一般に、このフレームワークへの賛辞は多くの記事で歌われていますが、実際には、サポートが容易になり、専門家を検索できるようになります。



モデル作成



特にエンジンを「捨てる」場合は、データが最も重要です。 したがって、現在のデータベースからデータを取得して新しいエンジンの開発を開始するのは理にかなっています。 symfonyの場合、モデルを作成します。 実際、ここではすべてが非常に簡単です。Doctrine:mapping:importコマンドを使用して基本的なフィールドを作成できます(詳細はこちらを参照してください)。 すべてのテーブルを一度に処理しないために、チームはメインテーブル(注文、チケット、イベント、ユーザー、およびリンクと拡張データのいくつかのテーブル)のみが残された、削除されたデータベースで実行されました。



ここで最初の問題に対処できます。 私たちのデータベースは列挙型であることが判明しましたが、ドクトリンは決して消化したくありませんが、数時間の作業で、列挙型を文字列/数字で置き換えたこれらのフィールドへの移行(ドクトリンの移行ではなく、単なるSQLファイルを意味します)になりました。



カラムを少し操作したので、施設で簡単に接続できます。 もちろん、古い開発者があなたの面倒を見て、主キーをリンクまたは1つ/多くのリンクを記述することができるいくつかの列として使用しない限り。 だからここで少し幸運です。



ほぼラッキー。 2番目の問題は順序に関するものであることが判明しました。単語の順序は予約されています。テーブルの1つには、このフィールドに順序IDを含む列があります(プロジェクトの作成者のおかげで、単語順序ではなく他のテーブルでord_idを予期せず使用し始めました)。 ここでは、簡単な解決策のうち、ダウンロードによるハッキングのみがありました。



public function postLoad(LifecycleEventArgs $event) { $entity = $event->getEntity(); if ($entity instanceof Ticket) { // getOrderNumber       order $id = $entity->getOrderNumber(); if ($id) { $order = $event->getEntityManager()->getRepository('AppBundle:Orders')->find($id); if (!$order) { throw new \Exception(sprintf("Order %d not found in base", $id)); } // setOrder/getOrder        orderObject       $entity->setOrder($order); } } }
      
      







コメントのオプションについて議論した後、ユーザーmyLizzarDが、今回は完全な接続を使用して、別のバージョンのハックにプッシュしました。



  /** *   * @ORM\Table(name="`orders`") */ /** *    * @ORM\ManyToOne(targetEntity="Orders") * @ORM\JoinColumn(name="order", referencedColumnName="id", nullable=true) */ private $order; //          public function preUpdate(PreUpdateEventArgs $args) { $entity = $args->getEntity(); if ($entity instanceof Ticket) { if ($changes = $args->getEntityChangeSet()) { if (isset($changes['order'])) { $em = $args->getEntityManager(); $uow = $em->getUnitOfWork(); $metadata = $em->getClassMetadata(Ticket::class); //  ,        $data = $uow->getOriginalEntityData($entity); $data['order'] = $changes['order'][1]; $uow->setOriginalEntityData($entity, $data); // ,    order $query = sprintf( 'UPDATE `%s` SET `order` = %s WHERE id = %d', $metadata->table['name'], $changes['order'][1] instanceof Orders ? $changes['order'][1]->getId() : 'null', $entity->getId() ); $em->getConnection()->executeQuery($query); //    ,        // ,      ,     $uow->clearEntityChangeSet(spl_object_hash($entity)); $uow->recomputeSingleEntityChangeSet($metadata, $entity); } } } }
      
      





3番目の問題は移行とデフォルト値で発生しました。これらも手作業で入力する必要があり、シンフォニー用に複製する必要があったため、次のようなものが得られました。



 /** * @ORM\Column(type="integer", options={"default" = 0}) */ public $type = 0;
      
      





クラウン交換



新しいエンジンの導入はどこから始めますか? プロジェクトがテストでカバーされていない場合、顧客を失うことなく壊れることを恐れないのは何ですか? ビジネス所有者にとって特に面白くない「汚い」作品はどこにありますか? どこでロジックを実装できますが、古いサイトのテンプレートを統合する必要はありませんか? そのため、新しいエンジンの火災の洗礼を選択することができました。 私が彼を交換したかった少なくとももう1つの理由は、古いエンジンではwgetが呼び出されたことでした。



はい、この段階で最初の問題を見つけましたが、チケットを購入できないよりも、チケットが必要以上に保留されている方が良いです。



最初のステップ(個別のウィジェット)



新しいエンジンに実装された2番目のブロックは、パートナー向けの予期せぬターンアップウィジェットです。 彼自身からすると、彼はアフィリエイトサイトのiframeを介して埋め込まれた小さなページでした。 また、このページでは、管理パネルで個別の管理が必要でした。 正直なところ、要件を読んで、新しいエンジンが火の洗礼を受けたばかりであることに気付いたとき、私はそれが単に理想的であり、不可能であると考えました。



iframe自体、レイアウトを個別に、テンプレートを個別に、さらに別のテーブルでさえ、表示する必要があるものを制御するのに問題はありません。 しかし、これらはすべて管理パネルで編集する必要があり、最も重要なことは、ユーザーが違いを感じないように(またはより良いと感じただけ)でした。 そのため、承認とフォームの表示という2つの問題を解決する必要がありました。



最初はガードメカニズムを通して決定されまし 。 必要なことは、ロジックを古いコードからgetCredentialsおよびgetUserメソッドに転送することだけでした。 私たちのプロジェクトでは、すべてのロジックが10行未満で済みました。 シンフォニーでの5年間、私はこれまでにない高速な認証設定と1つのクラスしか持っていませんでした。 外観の問題は、 フォームスタイリングすることで簡単に解決されまし



Nginxのセットアップ



次に、このすべての奇跡を開始する必要があります。 古いプロジェクトでは、nginx + apacheバンドルが使用されており、パス分離を使用してApache構成を実際に構成できる人はほとんどいないため、php-fpmを使用した2番目のバックエンドが編成されました。 新しいパスはapp.phpに送信され、彼は新しいプロジェクトフォルダーのルートと共にfpmに送信されました。 実際、ほぼそのようなコードが構成に追加されました。



 location ~ ^/admin/parnter { root /path-to-new-engine/web; try_files $uri /app.php$is_args$args; } location ~ ^/app\.php(/|$) { root /path-to-new-engine/web; Internal; ...fast_cgi config... }
      
      





結果は何ですか?



現時点では、コンセプトからすでに機能しているものに一歩進んだと言えます。 全体として、前向きな経験が得られ、この段階で生じた問題はほとんど問題とは言えず、むしろプログラミングの日です。 また、心理的な効果も忘れないでください。現在、これは終わりもエッジもないプロジェクトのようなものではありません。間違いなく開発者を引き付ける新しい開発の導入の見通しがあります。 また、顧客はプロジェクトでより有名で予測可能なツールを使用し始めたため、プラスの効果がありました。そのため、彼のウィッシュリストの一部では、リードタイムを短縮し始めましたが、これは新しいチップの開発コストの削減にも影響を与えました。 もちろん、全員ではありませんが、何かから始めなければなりませんでした。



All Articles